比赛 2008haoi模拟训练4 评测结果 AEAAWWEEEA
题目名称 遗传密码 最终得分 40
用户昵称 BYVoid 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2008-04-24 20:55:23
显示代码纯文本
#include <iostream>
#include <fstream>
#define MAXN 1001
#define MAXM 50000

using namespace std;

class ufs
{
public:
	long *father;
	long n;
	long find(long k)
	{
		long F,e=k,t;
		while (father[e]>0) e=father[e];
		F=e;
		e=k;
		while (father[e]>0)
		{
			t=e;
			e=father[e];
			father[t]=F;
		}

		return e;
	}
	ufs(long a)
	{
		long i;
		n=a;
		father=(long *)malloc((n+1)*sizeof(long));
		for (i=1;i<=n;i++)
			father[i]=-i;
	}	
	bool judge(long a,long b)
	{
		return father[find(a)]==father[find(b)];
	}
	void uni(long a,long b)
	{
		father[find(b)]=find(a);
	}
};



ifstream fi("pie.in");
ofstream fo("pie.out");

long m,n=0,ans,cp=0,adder=0;
long C[MAXN],od[MAXN],id[MAXN];
bool dis[MAXN][MAXN];
bool visited[MAXN];
bool used[MAXN];
ufs *U;


void init()
{
	long i,a,b;
	fi >> m;
	memset(dis,0,sizeof(dis));
	memset(used,0,sizeof(used));
	memset(visited,0,sizeof(visited));
	for (i=1;i<=m;i++)
	{
		fi >> a >> b;
		od[a]++;
		id[b]++;
		dis[a][b]=true;
		used[a]=used[b]=true;
		if (a>n) n=a;
		if (b>n) n=b;
	}
	U=new ufs(n);
}

void fs(long i)
{
	visited[i]=true;
	long j;
	for (j=1;j<=n;j++)
	{
		if (dis[i][j] && !visited[j])
		{
			U->uni(i,j);
			fs(j);
		}
	}
}

void bs(long i)
{
	visited[i]=true;
	long j;
	for (j=1;j<=n;j++)
	{
		if (dis[j][i] && !visited[j])
		{
			U->uni(i,j);
			bs(j);
		}
	}
}

void fcount()
{
	long yy,cnty=0,i,ck=0;
	fs(1);
	bs(1);
	for (i=1;i<=n;i++)
	{
		if (visited[i])
			ck++;
		yy=id[i]-od[i];
		if (yy>0)
			cnty+=yy;
	}

	if (cnty==0 && ck==n) //本身是欧拉回路
	{
		fo << n+1;
		fi.close();
		fo.close();
		exit(0);
	}
	memset(id,0,sizeof(id));
	memset(od,0,sizeof(od));
}

void connected()
{
	C[++cp]=1;
	long i,j;
	for (i=2;i<=n;i++)
	{
		if (visited[i] || !used[i]) continue;
		fs(i);
		bs(i);
		C[++cp]=i;
	}
}

void join()
{
	long i,j,a,b,yy,mx,m;
	for (i=2;i<=cp;i++)
	{
		a=C[i];
		mx=0;
		for (j=1;j<=n;j++)
		{
			if (U->judge(a,j))
			{
				yy=id[j]-od[j];
				if (yy>mx)
				{
					mx=yy;
					m=j;
				}
			}
		}
		a=m;
		mx=0x7FFFFFFF;
		b=C[i-1];
		for (j=1;j<=n;j++)
		{
			if (U->judge(b,j))
			{
				yy=id[j]-od[j];
				if (yy<mx)
				{
					mx=yy;
					m=j;
				}
			}
		}
		b=m;
		dis[a][b]=true; //a盈余,b亏损
		od[a]++;
		id[b]++;
		adder++;
	}
}

void degree()
{
	long i,j;
	for (i=1;i<=n;i++)
	{
		for (j=1;j<=n;j++)
		{
			if (dis[i][j] && used[i] && used[j])
			{
				od[i]++;
				id[j]++;
			}
		}
	}
}

void count()
{
	long yy,cnty=0,i;
	for (i=1;i<=n;i++)
	{
		yy=id[i]-od[i];
		if (yy>0)
			cnty+=yy;
	}
	adder+=cnty;
	ans=adder+m;
}

void print()
{
	fo << ans;
	fi.close();
	fo.close();
}

int main()
{
	init();
	fcount();
	connected();
	degree();
	join();
	count();
	print();
	return 0;
}