比赛 |
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;
}