cf1504. Travelling Salesman Problem

cf1504. Travelling Salesman Problem

题意:

n个城市,编号1~n,每个城市有美丽值a[i],现在要从城市1出发,其他所有城市走一遍,最后回到城市1,城市i到j的花费为max(ci,aj-ai),ci为第i个城市的最低消费
最低的总消费是多少?

题解:

(题解来自官方题解)
费用 = max (ci ,aj - ai)= ci +max(0,aj-ai-ci)
因为所有城市都要经过,所以ci是固定消费,我们现在要做的就是最小化max(0,aj-ai-ci)的总和
我们注意ai,ci一定是大于0的,要让这个max最小化,我们就尽可能让他等于0,也就是aj - (ai+ci)<=0
如果ai>aj,那么从城市i到城市j就是免费的(这里不考虑固定的ci消费,只考虑max的情况),所以我们只需要找一条从a1到an的路,剩下的旅程可以免费完成,因为最短路径是最优的
贴上原题解(说实话我现在还不是很清楚,等脑子清楚了再解决)
在这里插入图片描述

代码:

#include <bits/stdc++.h>

using namespace std;

int main() {
    
    
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<pair<long long, long long>> ve;
    long long ans = 0;
    for(int i = 0; i < n; i++) {
    
    
        long long a, c;
        cin >> a >> c;
        ve.push_back({
    
    a, c});
        ans += c;
    }
    sort(ve.begin(), ve.end());//以a为第一元素,b为第二元素
	//城市的美丽值是递增的 
	 
    //for(int i=0;i<n;i++)
    //	cout<<ve[i].first<<" "<<ve[i].second<<endl;
    long long mx = ve[0].first + ve[0].second;
    for(int i = 1; i < n; i++) {
    
    
        ans += max(0LL, ve[i].first - mx);
        mx = max(mx, ve[i].first + ve[i].second);
    }
    cout << ans << '\n';
}
#include <bits/stdc++.h>

using namespace std;

int main() {
    
    
    int n;
    cin >> n;
    vector<pair<long long, long long> > city;
    long long ans = 0;
    for(int i = 0; i < n; i++) {
    
    
        long long a, c;
        cin >> a >> c;
        city.push_back({
    
    a, c});
        ans += c;
    }
    sort(city.begin(), city.end());
    priority_queue<pair<long long, int>> Q;
    vector<bool> vis(n, false);
    Q.push({
    
    0, 0});
    while(!Q.empty()) 
	{
    
    
        long long d; int i;
        tie(d, i) = Q.top();//返回指向绑定的输出流的指针。
		Q.pop();
        if(vis[i]) continue;
        vis[i] = true;
        if(i == n - 1) {
    
    
            ans -= d;
            break;
        }
        if(i > 0) {
    
    
            Q.push({
    
    d, i - 1});
        }
        int j = lower_bound(city.begin(), city.end(), make_pair(city[i].first + city[i].second, LLONG_MAX)) - city.begin() - 1;
        //LLONG_MAX均存在与头文件limits.h,表示long long int 
		Q.push({
    
    d, j});
        if(j + 1 < n) {
    
    
            Q.push({
    
    d - city[j + 1].first + city[i].first + city[i].second, j + 1});
        }
    }
    cout << ans << '\n';
}

猜你喜欢

转载自blog.csdn.net/qq_35975367/article/details/115427641
今日推荐