Northwestern Europe Regional Contest (NWERC) 2018 Kattis - brexitnegotiations (贪心+拓扑排序)

Brexit Negotiations

As we all know, Brexit negotiations are on their way—but we still do not know whether they will actually finish in time.

The negotiations will take place topic-by-topic. To organise the negotiations in the most effective way, the topics will all be discussed and finalised in separate meetings, one meeting at a time.

This system exists partly because there are (non-cyclic) dependencies between some topics: for example, one cannot have a meaningful talk about tariffs before deciding upon the customs union. The EU can decide on any order in which to negotiate the topics, as long as the mentioned dependencies are respected and all topics are covered.

Each of the topics will be discussed at length using every available piece of data, including key results from past meetings. At the start of each meeting, the delegates will take one extra minute for each of the meetings that has already happened by that point, even unrelated ones, to recap the discussions and understand how their conclusions were reached. See Figure 1 for an example.

Nobody likes long meetings. The EU would like you to help order the meetings in a way such that the longest meeting takes as little time as possible.

\includegraphics[width=0.9\textwidth ]{sample1}

Figure 1: Illustration of how time is spent in each meeting in a solution to Sample Input 2.

Input

The input consists of:

  • One line containing an integer nn (1≤n≤4⋅1051≤n≤4⋅105), the number of topics to be discussed. The topics are numbered from 11 to nn.

  • nn lines, describing the negotiation topics.

    The iith such line starts with two integers eiei and didi (1≤ei≤1061≤ei≤106, 0≤di<n0≤di<n), the number of minutes needed to reach a conclusion on topic ii and the number of other specific topics that must be dealt with before topic ii can be discussed.

    The remainder of the line has didi distinct integers bi,1,…,bi,dibi,1,…,bi,di (1≤bi,j≤n1≤bi,j≤n and bi,j≠ibi,j≠i for each jj), the list of topics that need to be completed before topic ii.

It is guaranteed that there are no cycles in the topic dependencies, and that the sum of didi over all topics is at most4⋅1054⋅105.

Output

Output the minimum possible length of the longest of all meetings, if meetings are arranged optimally according to the above rules.

Sample Input 1Sample Output 1
3
10 0
10 0
10 0
12
Sample Input 2Sample Output 2
6
2 2 4 3
4 1 5
1 2 2 4
3 1 5
2 0
4 1 3
8

题意:

给你n(n<=4e5) 件物品的加工所需时间和其d(d<n)个前导编号,表示那些物品开始加工后才可以加工该物品,可以多个物品同时加工,但是物品开始加工的时间不能相同。

求最少的时间,加工完所有的物品。

思路:

建立反序图,考虑利用优先队列进行贪心的拓扑排序。

我们让层数低的,用时最少的物品优先匹配较大的时间(即前面最多有n-1件物品比它先开始)

然后取每件物品结束时的最大值即可。(好好想想这样为什么正确)

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=400010;
int n,m,k;
ll a[maxn];
int ru[maxn];
ll c[maxn],d[maxn];
vector<int>vc[maxn];
int ans,ct,cnt,tmp,flag;
char s[maxn];
bool vis[maxn];
struct node
{
    int id;
    ll v;
    bool operator<(node aa)const
    {
        return v>aa.v;
    }
};
void topo()
{
    ll ans=0;
    priority_queue<node>q;
    rep(i,1,n) if(ru[i]==0)
    {
        q.push(node{i,c[i]});
    }
    //cout<<q.top().v<<endl;
    ll t=n;
    while(!q.empty())
    {
        t--;
        node x=q.top();q.pop();
        ans=max(ans,x.v+t);
        for(int i=0;i<vc[x.id].size();i++)
        {
            int v=vc[x.id][i];
            if(--ru[v]==0) q.push(node{v,c[v]});
        }
    }
    printf("%lld\n",ans);
}
int main()
{
    int T,cas=1;
    while(scanf("%d",&n)!=EOF)
    {
        rep(i,0,n) {vc[i].clear();ru[i]=0;}
        ans=0;   flag=1;
        int x;
        rep(i,1,n)
        {
            scanf("%lld",&c[i]);
            scanf("%d",&d[i]);
            rep(j,1,d[i])
            {
                scanf("%d",&x);
                vc[i].push_back(x);
                ru[x]++;
            }
        }
        topo();
        //printf("%d\n",ans);
      //  if(flag) puts("Yes"); else puts("No");
    }
    return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值