The 2019 China Collegiate Programming Contest Harbin Site E - Exchanging Gifts 拓扑图+离散化

非常难受的是,我用链表写的,要么wa,要么tle,甚至还出现了超内存。。。
然后换成矩阵,开始还是wa了两次,然后换了别的快读,才过,难受。

#include<map>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define typeinput int
inline char nc()
{
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(typeinput &sum)
{
	char ch=nc();
	sum=0;
	while(!(ch>='0'&&ch<='9')) ch=nc();
	while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();
}
const int N=1e6+10;
ll a[N];
ll b[N];
int mark[N];
int vis[N];
int dp[N][2];
ll val[N];
int l[N];
int id[N];
vector<int> G[N];
int in[N];
ll mp[N];
int k;
int cnt;
int pp[N];
void bfs(int n,int s)
{
	val[s]=1;
	queue<int>q; 
	for(int i=1; i<=n; i++)
		if(!in[i])
			q.push(i);
	while(q.size())
	{
		int u=q.front();
		q.pop();
		for(int i=0; i<G[u].size(); i++)
		{
			int v=G[u][i];
			in[v]--;
			val[v]+=val[u];
			if(in[v]==0)
				q.push(v);
		}
	}
}
void init(int n)
{
	cnt=0;
	for(int i=0;i<=n;i++)
		vis[i]=val[i]=in[i]=0;
}
int main()
{
	int T;
	read(T);
	while(T--)
	{
		int n;
		read(n);
		init(n);
		for(int i=1; i<=n; i++)
		{
			//初始化数组 
			mark[i]=cnt;
			G[i].clear();
			//类型 
			read(id[i]);
			if(id[i]==1)
			{
				read(k);
				//当前数组的元素个数 
				l[i]=k;
				for(int i=0; i<k; i++)
				{
					int x;
					read(x);
					//记录当前数字 
					a[cnt++]=x;
				}
			}
			else
			{
				int x,y;
				read(x);
				read(y);
				dp[i][0]=x;dp[i][1]=y;
				//入度 
				in[x]++;in[y]++;
				G[i].push_back(x);G[i].push_back(y);
				vis[i]=1;
			}
		}
		for(int i=0; i<cnt; i++) 
			b[i]=a[i];
		sort(b,b+cnt);
		int len=unique(b,b+cnt)-b;
		for(int i=0; i<len; i++) 
			mp[i]=0;
		for(int i=0; i<cnt; i++)
			a[i]=lower_bound(b,b+len,a[i])-b;
		//如果最终序列直接给出 
		if(id[n]==1)
		{
			ll maxv=0;
			for(int i=mark[n]; i<mark[n]+l[n]; i++)
			{
				mp[a[i]]++;
				if(mp[a[i]]>maxv) 
					maxv=mp[a[i]];
			}
			if(2*maxv<=l[n])
				printf("%lld\n",l[n]);
			else
				printf("%lld\n",2ll*(l[n]-maxv));
		}
		else
		{
			bfs(n,n);
			ll maxx=0;
			ll tot=0;
			for(int i=1; i<=n; i++)
			{
				//不在最终序列中 
				if(vis[i] || !val[i]) 
					continue;
				//总个数 
				tot+=1ll*l[i]*val[i];
				//					原数组中的数 
				for(int j=mark[i]; j<mark[i]+l[i]; j++)
				{
					mp[a[j]]+=val[i];
					maxx=max(maxx,mp[a[j]]);
				}

			}
			if(2*maxx<=tot)
				printf("%lld\n",tot);
			else
				printf("%lld\n",2ll*(tot-maxx));
		}
	}
	return 0;
}


posted @ 2020-04-12 17:49  晴屿  阅读(172)  评论(0编辑  收藏  举报