Exchanging Gifts 【拓扑】

来源

https://codeforces.com/gym/102394/problem/E

思路

代码

拓扑排序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define pb push_back 
#define sz(x) (x).size()
#define dd(x) cout<<#x<<'='<<x<<' '
#define de(x) cout<<#x<<'='<<x<<endl
#define fi first
#define se second

inline bool read(ll &ret){
	char c;
	ll sgn;
	if(c=getchar(),c==EOF){
		return 0;
	}
	while(c!='-'&&(c<'0'||c>'9')){
		c=getchar();
	}
	sgn=(c=='-')?-1:1;
	ret=(c=='-')?0:(c-'0');
	while(c=getchar(),c>='0'&&c<='9'){
		ret=ret*10+(c-'0');
	}
	ret*=sgn;
	return 1;
}



vector<ll> fa[1000010];
vector<ll> a[1000010];
ll kk[1000010],du[1000010];

unordered_map<ll,ll> cnt;
ll maxx,sum;

void topo(ll st,ll n){
	cnt.clear();
	maxx=sum=0;
	queue<ll> q;
	for (int i=1; i<=n; i++)
		if (du[i]==0) q.push(i);
	kk[st]=1;
	while (!q.empty()){
		ll u=q.front();
		q.pop();
		if (fa[u].empty()){
			for (ll i=0; i<sz(a[u]); i++){
//				dd(it.fi),de(it.se);
				cnt[a[u][i]]+=kk[u];
				maxx=max(maxx,cnt[a[u][i]]);
				sum+=kk[u];
			}
		}
		else{
			for (ll i=0; i<sz(fa[u]); i++){
				ll v=fa[u][i];
				du[v]--;
				kk[v]+=kk[u];
				if (du[v]==0) q.push(v);
			}
			
		}
	}
//	dd(sum),de(maxx);
}



int main(){
//	ios::sync_with_stdio(false);
//	cin.tie(0);
//	cout.tie(0);
	ll t;
	read(t);
	while (t--){
		ll n;
		read(n);
		for (ll i=1; i<=n; i++){
			ll op;
			read(op);
			if (op==1){
				ll k;
				read(k);
				for (ll j=1; j<=k; j++){
					ll qq;
					read(qq);
					a[i].pb(qq);
				}
			}
			if (op==2){
				ll x,y;
				read(x);
				read(y);
				fa[i].pb(x);
				fa[i].pb(y);
				du[x]++;
				du[y]++;
			}
		}
		topo(n,n);
		if (maxx>sum-maxx) cout<<(sum-maxx)*2LL<<endl;
		else cout<<sum<<endl;
		for (ll i=0; i<=n; i++) a[i].clear();
		for (ll i=0; i<=n; i++) fa[i].clear();
		for (ll i=0; i<=n; i++) du[i]=kk[i]=0;
	}
	return 0;
}

改进后

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define pb push_back 
#define sz(x) (x).size()
#define dd(x) cout<<#x<<'='<<x<<' '
#define de(x) cout<<#x<<'='<<x<<endl
#define fi first
#define se second

inline bool read(ll &ret){
	char c;
	ll sgn;
	if(c=getchar(),c==EOF){
		return 0;
	}
	while(c!='-'&&(c<'0'||c>'9')){
		c=getchar();
	}
	sgn=(c=='-')?-1:1;
	ret=(c=='-')?0:(c-'0');
	while(c=getchar(),c>='0'&&c<='9'){
		ret=ret*10+(c-'0');
	}
	ret*=sgn;
	return 1;
}



vector<ll> fa[1000010];
vector<ll> a[1000010];
ll kk[1000010],du[1000010];

map<ll,ll> cnt;
ll maxx,sum;

int main(){
	ll t;
	read(t);
	while (t--){
		ll n;
		read(n);
		for (ll i=1; i<=n; i++){
			ll op;
			read(op);
			if (op==1){
				ll k;
				read(k);
				for (ll j=1; j<=k; j++){
					ll qq;
					read(qq);
					a[i].pb(qq);
				}
			}
			if (op==2){
				ll x,y;
				read(x);
				read(y);
				fa[i].pb(x);
				fa[i].pb(y);
				du[x]++;
				du[y]++;
			}
		}
		cnt.clear();
		kk[n]=1;
		maxx=sum=0;
		for (int i=n; i>=1; i--){
			if (fa[i].empty()){
				for (int j=0; j<sz(a[i]); j++){
					cnt[a[i][j]]+=kk[i];
					maxx=max(maxx,cnt[a[i][j]]);
					sum+=kk[i];
				}
			}
			else{
				for (int j=0; j<sz(fa[i]); j++){
					kk[fa[i][j]]+=kk[i];
				}
			}
		}
//		cout<<maxx<<' '<<sum<<endl;
		if (maxx>sum-maxx) cout<<(sum-maxx)*2LL<<endl;
		else cout<<sum<<endl;
		for (ll i=0; i<=n; i++) a[i].clear();
		for (ll i=0; i<=n; i++) fa[i].clear();
		for (ll i=0; i<=n; i++) du[i]=kk[i]=0;
	}
	
	return 0;
}

参考文献

[1] https://blog.csdn.net/weixin_42856843/article/details/104460891

posted @ 2020-10-24 09:48  Synnn  阅读(174)  评论(0编辑  收藏  举报