note:
1、取迭代次数为n^2lgn
2、每次迭代时提前对边集进行shuffle (关键 idea)
3、并查集实现缩边
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<fstream>
using namespace std;
struct edge
{
int u,v;
}e[205*205];
int f[205];
int find(int x)
{
if(f[x]!=x)
f[x]=find(f[x]);
return f[x];
}
void merge(int u,int v)
{
f[find(u)]=f[v];
return ;
}
int main()
{
string s;
freopen("data.txt","r",stdin);
// freopen("data.txt","w",stdout);
// while(getline(cin,s))
// {
// cout<<s<<endl;
// cout<<201<<endl;
// }
int u,v,ecnt=0;
while(cin>>u)
{
while(cin>>v)
{
if(v==201)
break;
if(v<=u)
continue;
e[ecnt].u=u;e[ecnt].v=v;++ecnt;
}
}
int tcnt=1600,cnt,r,el,ans,ta;
ans=0x3fffffff;
while(tcnt)
{
--tcnt;
cnt=200;
srand(unsigned(time(0)));
for(int i=1;i<201;++i)
f[i]=i;
random_shuffle(e,e+ecnt);
el=0;
while(cnt>2)
{
while(find(e[el].u)==find(e[el].v))
{
++el;
}
u=e[el].u;v=e[el].v;
merge(u,v);
--cnt;
}
ta=0;
for(int i=0;i<ecnt;++i)
{
if(find(e[i].u)!=find(e[i].v))
++ta;
}
ans=min(ans,ta);
}
cout<<ans<<endl;
return 0;
}