codeforces round 433 D. Jury Meeting

题目大意:

输入n,m,k,分别代表城市的数量,城市编号1~n,航班的数量以及会议必须所有人员到会一起商议的天数,然后及时输入m行航班的信息,每一行输入d,f,t,c分别表示航班到站和始发的那一天(始发和到站是一天),f表示始发站,t表示目的地,c表示花费,然后f和t里必然有一个是0,表示要么是去0号城市,要么回到原来城市,题目要求就是,每个城市必须派人到0号城市参加会议,然后他们必须一块在0号城市k天,然后必须全部回到他们原来的城市才行(某个城市某个人到达0号城市之后可以愿意待多少天就待多少天,当然,回不去就尴尬了),让你求最小的花费,如果不能满足条件,输出-1;

基本思路:

最小费用分为0号城市的航班的费用和从0号城市飞回的费用,分别处理,然后贪心的话,就有一个问题,拿飞向0号城市的航班来说,到底是按照始发时间排序还是按照费用排序,想一下,如果按照费用排序,这个时间复杂度肯定过不了,那么就按照始发时间排序,这样,用一个dp数组记录总费用,下标是这n个航班的最晚始发时间,然后对于某一个最晚始发时间,最优的肯定是它和始发时间在它前面的最小费用了,然后就有这个dp【i】=min(dp【i-1】,dp【i】),这个点之前的最小费用就这样传递了过来,然后这样时间复杂度就是n,完全没问题;

反思与总结:

我只知道是贪心,并没有明确的贪心思路,看了题解才发现,类似的题目我也做过2个,真心菜,一定要扎实,首要目的是下次能a出这个题目啊;

代码如下:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll inf = 1e17;
const int maxn = 2000000+10;
const int maxx = 100000+10;

struct Node
{
    int d,f,t,c;
    bool operator<(const Node& a)const {return d<a.d;}
}node[maxx];
ll dp1[maxn],dp2[maxn],b[maxn];


int main()
{
    int n,m,k;
    while(scanf("%d%d%d",&n,&m,&k)==3)
    {
        for(int i=0;i<=maxn;i++) dp1[i]=inf,b[i]=-1;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&node[i].d,&node[i].f,&node[i].t,&node[i].c);
        }
        sort(node+1,node+m+1);
        int cnt=0;
        ll sum=0;
        for(int i=1;i<=m;i++)
        {
            if(node[i].f==0) continue;
            if(b[node[i].f]==-1)
            {
                b[node[i].f]=node[i].c;
                sum+=node[i].c;
                cnt++;
            }
            else
            {
                if(b[node[i].f]>node[i].c)
                {
                    sum-=b[node[i].f];
                    sum+=node[i].c;
                    b[node[i].f]=node[i].c;
                }
            }
            if(cnt==n) dp1[node[i].d]=sum;
        }
        sum=0;
        cnt=0;
        for(int i=0;i<=maxn;i++) dp2[i]=inf,b[i]=-1;
        for(int i=m;i>=1;i--)
        {
            if(node[i].t==0) continue;
            if(b[node[i].t]==-1)
            {
                b[node[i].t]=node[i].c;
                sum+=node[i].c;
                cnt++;
            }
            else
            {
                if(b[node[i].t]>node[i].c)
                {
                    sum-=b[node[i].t];
                    sum+=node[i].c;
                    b[node[i].t]=node[i].c;
                }
            }
            if(cnt==n) dp2[node[i].d]=sum;
        }
        int sign;
        for(int i=1;i<=maxn;i++) if(dp1[i]!=inf) {sign=i;break;}
        for(int i=sign;i<=1000000;i++) dp1[i]=min(dp1[i],dp1[i-1]);
        for(int i=1000000;i>=1;i--) if(dp2[i]!=inf) {sign=i;break;}
        for(int i=sign-1;i>=1;i--) dp2[i]=min(dp2[i],dp2[i+1]);
        ll res=inf;
        for(int i=1;i<=1000000;i++)
        {
            if(dp1[i]==inf||dp2[i+k+1]==inf) continue;
            res=min(res,dp1[i]+dp2[i+k+1]);
        }
        if(res==inf) printf("-1
");
        else printf("%I64d
",res);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/imzscilovecode/p/7490696.html