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

Posted qingyuyyyyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",l[n]);
			else
				printf("%lld
",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
",tot);
			else
				printf("%lld
",2ll*(tot-maxx));
		}
	}
	return 0;
}


以上是关于The 2019 China Collegiate Programming Contest Harbin Site E - Exchanging Gifts 拓扑图+离散化的主要内容,如果未能解决你的问题,请参考以下文章

The 2019 China Collegiate Programming Contest Harbin Site F. Fixing Banners

The 2019 China Collegiate Programming Contest Harbin Site I. Interesting Permutation

The 2019 China Collegiate Programming Contest Harbin Site K. Keeping Rabbits

The 2019 China Collegiate Programming Contest Harbin Site I - Interesting Permutation 思维

The 2019 China Collegiate Programming Contest Harbin Site A - Artful Paintings 差分约束

Rolling The Polygon (2018-2019 ACM-ICPC, China Multi-Provincial Collegiate Programming Contest)(The