防爆秃击队——组队训练11:Gym - 102483B B - Brexit Negotiations

1.题目描述:
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 the figure 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.

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 n (1≤n≤4⋅105), the number of topics to be discussed. The topics are numbered from 1 to n.
n lines, describing the negotiation topics.
The ith such line starts with two integers ei and di (1≤ei≤106, 0≤di<n), the number of minutes needed to reach a conclusion on topic i and the number of other specific topics that must be dealt with before topic i can be discussed.

The remainder of the line has di distinct integers bi,1,…,bi,di (1≤bi,j≤n and bi,j≠i for each j), the list of topics that need to be completed before topic i.
在这里插入图片描述
It is guaranteed that there are no cycles in the topic dependencies, and that the sum of di over all topics is at most 4⋅105.
Output
Output the minimum possible length of the longest of all meetings, if meetings are arranged optimally according to the above rules.

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

2.题意:
给出n个主题,每个主题有固定的讨论主题,讨论某个主题前有若干个前置主题需要讨论,每次会议开始时先花1分钟复习之前开过的会议(无论关联与否)。求最长会议的最小可能时长。

3.思路:
是3小时罚坐死磕题QwQ。一开始秒想到贪心+拓扑排序。奈何一手建图毁于一旦,好好的题硬是3个小时没写出来T_T。这题要反向建边! 为什么呢?首先我们如果对前面的大会议按从大到小这样分配,会有WA点——前驱节点的值过小,导致后继节点的大值无法优先选择。
例如:
4
1 0
100 1 1
2 0
3 0
这组数据,就可以完美卡死从前建图跑优先队列的了。反向建图是从最后一批会中挑选出小的来安排靠后的时间,后面的并不会影响前面的安排,因而符合贪心的要素。

4.代码:

//B - Brexit Negotiations
//#include<bits/stdc++.h>
//#pragma GCC optimize(3,"Ofast","inline")
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
//#include<random>
#include<cstdlib>
#include<ctime>
#include<fstream>
#include<map>
#include<stack>
#include<queue>
#define FAST ios::sync_with_stdio(false)
#define DEV_RND ((int)rand()*RAND_MAX+rand())
#define RND(L,R) (DEV_RND%((R)-(L)+1)+(L))
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<n;++i)
#define repn(i,a,n,t) for(int i=a;i<n;i+=t)
#define per(i,n,a) for(int i=n-1;i>=a;--i)
#define pern(i,n,a,t) for(int i=n-1;i>=a;i-=t)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define li inline
#define re register
using namespace std;
//typedef uniform_int_distribution<int> RNDI;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef double db;
typedef long long ll;
typedef long double ld;
const int maxn = 4e5+5;
const int maxm = 100000+5;
const int inf=0x3f3f3f3f;
const double eps = 1e-9;
const double pi=acos(-1);
const int mod = 1e9+7;
//int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
//li int f(int x){return x==par[x]?par[x]:par[x]=f(par[x]);}
//mt19937 eng(time(0));
li ll lowbit(ll x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
//li int RND(int L,int R){RNDI rnd(L,R);return rnd(eng);}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
li ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
li ll qmul(ll a,ll b,ll MOD=mod){return (a*b-(ll)((long double)a/MOD*b)*MOD+MOD)%MOD;}
li ll Qpow(ll a,ll b,ll MOD){ll res=1;while(b>0){if(b&1) res=qmul(res,a,MOD);a=qmul(a,a,MOD);b>>=1;}return res;}
li ll invp(ll x,ll p){return qpow(x,p-2,p);}
ll invd(ll x,ll p){ll res,d,t;ex_gcd(x,p,d,res,t);return res;}
li ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
namespace IO
{
	li int read()
	{
		int x=0,sign=1;char c=getchar();
		while(c>'9'||c<'0') {if(c=='-') sign=-1;c=getchar();}
		while('0'<=c&&c<='9') x=x*10+c-'0',c=getchar();
		return x*sign;
	}
	template<typename T>
	li void write(T x,char t='\n')
	{
		if(x<0){x=-x;putchar('-');};
		static int sta[25];int top=0;
		do{sta[top++]=x%10,x/=10;}while(x);
		while(top) putchar(sta[--top]+'0');
		putchar(t);
	}
}
using namespace IO;
/*-------------head-------------*/
int n,m,mx;
struct node
{
	int u;
	int e;
	bool operator<(const node& a)const
	{
		return e>a.e;
	}
}num[maxn];
vector<int> G[maxn];
int inDegree[maxn];
void Topsort()
{
	int cnt=n;
	priority_queue<node> q;
	rep(i,1,n+1) if(!inDegree[i]) q.push(num[i]);
	while(!q.empty())
	{
		--cnt;
		node t=q.top();q.pop();
		int u=t.u;
		mx=max(t.e+cnt,mx);
		rep(i,0,sz(G[u]))
		{
			int v=G[u][i];
			if(--inDegree[v]==0) q.push(num[v]);
		}
	}
}
//
li void solve()
{
	mx=0;
	rep(i,1,n+1) G[i].clear(),inDegree[i]=0;
	rep(i,1,n+1)
	{
		num[i].u=i;
		num[i].e=read();
		m=read();
		while(m--)
		{
			int x=read();
			G[i].pb(x);
			inDegree[x]++;
		}
	}
	Topsort();
	write(mx);
	//puts("");
}
int main()
{
	//srand(time(0));debug();
	//clock_t start_time=clock();
	//freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
	//for(int QwQ=read();QwQ;QwQ--) solve();
	while(~scanf("%d",&n)) solve();
	//cerr<<"Time:"<<clock()-start_time<<"ms\n";
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值