Northwestern Europe Regional Contest (NWERC) 2018 B. Kattis - brexitnegotiations 拓撲排序 貪心

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.

題意:有n個會議,每個會議有個時長且開始前要完成前導會議,而且當前會議開始前要加上開過的會議*1分鐘,問最少的花費時間

思路(拓撲排序+貪心):

隊友一開始正向建邊一直卡在test13,後來發現反向建邊有奇效。反過來看,最後一個要完成的會議,它的產生時長是確定的,即是當前點權+n-1(之前的會議),然後對於前一層,貪心地挑出最小的時長,分配n-2的會前時間,這樣能使得和它相連的會議額外加上的時長儘量的少。 比如 最後一個結點1, 有2,3,4的前導結點,點權分別是2, 3,4,那麼最後一個結點時長1+3 , 下一層 2 + 2, 3 + 1, 4 + 0,使得最後的時長最小化爲4 。(不然最後一場會議之前是結點4的話就是4+2了)。然後藉助拓撲排序的思想,把所有結點遍歷一遍

AC代碼:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#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 per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define maxm 100000+500
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int maxn = 4e5+5;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
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);
inline 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;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline 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;}
inline ll read(){ ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') ch = getchar();while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
vector< vector<ll> > D(maxn);
ll n;
ll m;
ll in[maxn];vector<ll> ans(maxn);
ll val[maxn];
ll ma = -1;

void init()
{
    ma = -1;
    mem(in,0);
    rep(i,1,n) D[i].clear();
}

void Topsort()
{
    priority_queue<PII , vector<PII>, greater<PII> > q;
    rep(i,1,n) if(in[i]==0) q.push(mp(val[i],i));
    ll num = n;
    while(!q.empty())
    {
        ll cur = q.top().se, wi = q.top().fi ; q.pop();
        num--;
        ma = max(ma,wi+num);
        if(D[cur].size()==0) continue;
        rep(i,0,D[cur].size()-1)
        {
            ll v = D[cur][i];    in[v] --;
            if(in[v]==0)
            {
                q.push(mp(val[v],v));
            }
        }
    }
}
int main()
{
    FAST;
    cin>>n;
    init();
    rep(i,1,n)
    {
        cin>>val[i];
        ll V;
        cin>>V;
        rep(j,1,V)
        {
            ll x; cin>>x;
            D[i].pb(x);
            in[x] ++;
        }
    }
    Topsort();
    cout<<ma<<endl;
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章