Kattis - brexitnegotiations (Northwestern Europe Regional Contest (NWERC) 2018)

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.

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

    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 most 4⋅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 1 Sample Output 1
3
10 0
10 0
10 0
12
Sample Input 2 Sample Output 2
6
2 2 4 3
4 1 5
1 2 2 4
3 1 5
2 0
4 1 3
8

 

 

题意:

n个会议,前i组有t,m,id[1],id[2],id[3]......id[m],第i个会议需要t时间,且有m组的先前任务(必须完成m个任务才能做第i个任务)。

每开一次会议的时间=t+前面已经开的会议的次数,求最大的时间的最短。

分析:

可能会绕到拓扑排序+大根堆优先队列的坑里,但其实是错误的。优先选择大的是不对的,因为

1:小  2:大(超级大)

3:大  4:小

按照我们拓扑排序+大根堆优先队列会优先选择不对。

接下来有两种解法:

1.逆向

反向拓扑+小根堆,利用拓扑排序找到最底层的节点,因为时间是倒着来的,所以先找时间最短的会议。

2.dfs+排序

整体思想:每一次都找当前会议集合的最长时间会议,用dfs建立其该会议的前驱任务,用vis数组记录是否开过。

但1应该是正解

官方题解:

 

Kattis - brexitnegotiations (Northwestern Europe Regional Contest (NWERC) 2018)_第1张图片

Kattis - brexitnegotiations (Northwestern Europe Regional Contest (NWERC) 2018)_第2张图片

反向拓扑+小根堆

#include 
using namespace std;
typedef long long LL;
const int N=400005;
vector G[N];
int in[N],v[N];
int vis[N];
int n;
int cnt;
struct node
{ 
	int id,d;
    friend bool operator<(node a,node b)//d从大到小排序
    {
        return b.dQ;
    // priority_queue,greater >q;//保证小值先出队列 按照字典序
    for(int i=1;i<=n;i++)
	{
		if(in[i]==0)
	     {
	     	x.id=i;
	     	x.d=v[i];
	     	Q.push(x);
	     	vis[i]=1;
	     }
	}
    int t=0;
	ans=-1e9;
	while(!Q.empty())//WA考虑用vis数组
	{
	    y=Q.top();
		Q.pop();
	
		sum--;
	    ans=max(ans,v[y.id]+sum);
	    for(int i=0;i

 

dfs+排序

#include 
using namespace std;
typedef long long LL;
const int N=400005;
vector G[N];
int vis[N],v[N];
int n;
struct node
{ 
	int id,d;
    friend bool operator<(node a,node b)//d从大到小排序
    {
        return b.d

 

你可能感兴趣的:(图论——拓扑排序,好题)