</pre><pre name="code" class="cpp">for (i=1;i<=n;++i) father[i]=i;查找
int find(int x)//(路径压缩) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; }合并
int union(int x,int y) { int r1,r2; r1=find(x); r2=find(y); if (r1!=r2) father[r1]=r2;//(视具体情况合并关系不同)Easy
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int father[100001],root,use[100001]; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int x,y,r1,r2,maxn,minn,t,i; bool f; t=0; while ((x!=-1)||(t==0)) { scanf("%d%d",&x,&y); if (x==-1) break; t++; f=true; memset(use,false,sizeof(use)); for (i=1;i<=100000;++i) father[i]=i; maxn=0; minn=100000; while (x!=0) { r1=find(x); use[x]=true; r2=find(y); use[y]=true; maxn=max(maxn,max(x,y)); minn=min(minn,min(x,y)); if (r1!=r2) father[r2]=r1; else f=false; scanf("%d%d",&x,&y); } root=find(minn); cout<<root<<endl; for (i=minn+1;i<=maxn;++i) if ((find(i)!=root)&&(use[i])) {f=false; break;} if (f) cout<<"Case "<<t<<" is a tree."<<endl; else cout<<"Case "<<t<<" is not a tree."<<endl; } }2.POJ 1611 The Suspects
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int father[30001],n,q,m; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int j,i,r1,r2,x,y,root,ans; scanf("%d%d",&n,&q); while (n!=0) { for (i=0;i<=n;++i) father[i]=i; for (j=1;j<=q;++j) { scanf("%d%d",&m,&x); r1=find(x); for (i=2;i<=m;++i) { scanf("%d",&y); r2=find(y); if (r1!=r2) father[r2]=r1; } } ans=0; root=find(0); for (i=0;i<=n;++i) if (find(i)==root) ans++; cout<<ans<<endl; scanf("%d%d",&n,&q); } } 3 POJ 2524 Ubiquitous Religions 大致题意 输入n个点之间的关系,最后输出有几个集合(多组数据)。 初始化集合数为结点数,每成功合并一次集合数就减一,最后输出即可。 code: #include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,q,father[50001]; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int i,r1,r2,x,y,ans,t; t=0; scanf("%d%d",&n,&q); while (n!=0) { t++; ans=n; for (i=1;i<=n;++i) father[i]=i; for (i=1;i<=q;++i) { scanf("%d%d",&x,&y); r1=find(x); r2=find(y); if (r1!=r2) { ans--; father[r1]=r2; } } cout<<"Case "<<t<<": "<<ans<<endl; scanf("%d%d",&n,&q); } } 4.POJ 2236 Wireless Network 大致题意:东南亚大地震(神题意),电脑坏了,需要一台一台修,修好后可与一定欧拉距离D联网,询问i,j之间是否联网;多组数据 很裸的思路,每修好一个电脑与其距离小于D的且修好的电脑合并即可。 code: #include<iostream> #include<cstdio> #include<cstring> using namespace std; bool rep[1002]; int father[1002],dis[1002][2],n,p; int ola(int x,int y) { return (dis[x][0]-dis[y][0])*(dis[x][0]-dis[y][0])+(dis[x][1]-dis[y][1]) *(dis[x][1]-dis[y][1]); } int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int i,x,y,r1,r2; char ch; memset(rep,false,sizeof(rep)); scanf("%d%d",&n,&p); for (i=1;i<=n;++i) father[i]=i; for (i=1;i<=n;++i) scanf("%d%d",&dis[i][0],&dis[i][1]); while (scanf("%*c%c",&ch)==1) { if (ch=='O') { scanf("%d",&x); rep[x]=true; for (i=1;i<=n;++i) if ((ola(x,i)<=p*p)&&(rep[i])) { r1=find(x); r2=find(i); if (r1!=r2) father[r1]=r2; } } if (ch=='S') { scanf("%d%d",&x,&y); r1=find(x); r2=find(y); if (r1!=r2) printf("FAIL\n"); else printf("SUCCESS\n"); } } }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,k,father[150001]; int find(int x) { if (father[x]!=x) father[x]=find(father[x]); return father[x]; } int main() { int i,kind,x,y,ans,r1,r2,r3,r4,r5,r6; scanf("%d%d",&n,&k); for (i=1;i<=3*n;++i) father[i]=i; ans=0; for (i=1;i<=k;++i) { scanf("%d%d%d",&kind,&x,&y); if ((x>n)||(y>n)) {ans++; continue;} r1=find(x); r2=find(y); r3=find(x+n); r4=find(y+n); r5=find(x+2*n); r6=find(y+2*n); if (kind==1) { if ((r2==r3)||(r2==r5)) { ans++; continue; } else { father[r1]=r2; father[r3]=r4; father[r5]=r6; } } if (kind==2) { if ((r1==r2)||(r5==r2)) { ans++; continue; } else { father[r3]=r2; father[r5]=r4; father[r1]=r6; } } } printf("%d\n",ans); }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int father[100001],gang[100001],t,n,m; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int i,j,x,y,r1,r2; char kind; scanf("%d",&t); for (i=1;i<=t;++i) { scanf("%d%d",&n,&m); for (j=0;j<=n;++j) father[j]=j; memset(gang,0,sizeof(gang)); for (j=1;j<=m;++j) { scanf("%*c%c",&kind); scanf("%d%d",&x,&y); r1=find(x); r2=find(y); if (kind=='D') if (r1!=r2) { if (gang[r1]==0) gang[r1]=r2; else if (find(gang[r1])!=r2) father[find(gang[r1])]=r2; if (gang[r2]==0) gang[r2]=r1; else if (find(gang[r2])!=r1) father[find(gang[r2])]=r1; } if (kind=='A') { if (r1==r2) cout<<"In the same gang."<<endl; if (r1!=r2) { if (find(gang[r1])!=r2) cout<<"Not sure yet."<<endl; else cout<<"In different gangs."<<endl; } } } } }
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int t,father[2001],e[2001],n,q; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int i,j,r1,r2,r3,x,y; bool f; scanf("%d",&t); for (i=1;i<=t;++i) { scanf("%d%d",&n,&q); memset(e,0,sizeof(e)); for (j=1;j<=n;++j) father[j]=j; f=true; for (j=1;j<=q;++j) { scanf("%d%d",&x,&y); r1=find(x); r2=find(y); if (r1==r2) f=false; else { if (e[r1]==0) e[r1]=r2; else { r3=find(e[r1]); if (r2!=r3) father[r2]=r3; } if (e[r2]==0) e[r2]=r1; else { r3=find(e[r2]); if (r1!=r3) father[r1]=r3; } } } if (f) { cout<<"Scenario #"<<i<<':'<<endl; cout<<"No suspicious bugs found!"<<endl<<endl; } else { cout<<"Scenario #"<<i<<':'<<endl; cout<<"Suspicious bugs found!"<<endl<<endl; } } }4.POJ 1733 Parity game(codevs 奇偶游戏,tyvj和vijos 小胖的奇偶)
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; long long l,n; int father[10001],pa[10001]={0}; long long a[10001],b[10001],kind[5001]; int find(int x) { int j; if (x!=father[x]) { j=find(father[x]); pa[x]+=pa[father[x]]; //更新距离; father[x]=j; } return father[x]; } int main() { int i,x,y,r1,r2,size; bool f=false; char s[10]; scanf("%lld%d",&l,&n); for (i=1;i<=n;++i) { scanf("%lld%lld",&a[i*2-1],&a[i*2]); a[i*2-1]--; b[i*2-1]=a[i*2-1]; b[i*2]=a[i*2]; scanf("%s",&s); if (s[0]=='e') kind[i]=0; if (s[0]=='o') kind[i]=1; } sort(b+1,b+2*n+1); size=unique(b+1,b+2*n+1)-b-1; for (i=1;i<=2*n;++i) a[i]=upper_bound(b+1,b+size+1,a[i])-b-1;// 这之上为离散化 for (i=1;i<=size;++i) father[i]=i; for (i=1;i<=n;++i) { x=a[2*i-1]; y=a[2*i]; r1=find(x); r2=find(y); if (r1!=r2) { father[r2]=r1; pa[r2]=pa[x]+kind[i]-pa[y]; //关键语句 } if (r1==r2) { if (abs(pa[y]-pa[x])%2!=kind[i]) { cout<<i-1<<endl; f=true; break; } } } if (f==false) cout<<n<<endl; }5.POJ 1984 Navigation Nightmare
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; long long l,n; int father[10001],pa[10001]={0}; long long a[10001],b[10001],kind[5001]; int find(int x) { int j; if (x!=father[x]) { j=find(father[x]); pa[x]+=pa[father[x]]; //更新距离; father[x]=j; } return father[x]; } int main() { int i,x,y,r1,r2,size; bool f=false; char s[10]; scanf("%lld%d",&l,&n); for (i=1;i<=n;++i) { scanf("%lld%lld",&a[i*2-1],&a[i*2]); a[i*2-1]--; b[i*2-1]=a[i*2-1]; b[i*2]=a[i*2]; scanf("%s",&s); if (s[0]=='e') kind[i]=0; if (s[0]=='o') kind[i]=1; } sort(b+1,b+2*n+1); size=unique(b+1,b+2*n+1)-b-1; for (i=1;i<=2*n;++i) a[i]=upper_bound(b+1,b+size+1,a[i])-b-1;// 这之上为离散化 for (i=1;i<=size;++i) father[i]=i; for (i=1;i<=n;++i) { x=a[2*i-1]; y=a[2*i]; r1=find(x); r2=find(y); if (r1!=r2) { father[r2]=r1; pa[r2]=pa[x]+kind[i]-pa[y]; //关键语句 } if (r1==r2) { if (abs(pa[y]-pa[x])%2!=kind[i]) { cout<<i-1<<endl; f=true; break; } } } if (f==false) cout<<n<<endl; }6.poj 1988 Cube Stacking
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int father[30001],son[30001],n,pa[30001]; int find(int x) { int j; if (x!=father[x]) { j=find(father[x]); pa[x]=pa[father[x]]+pa[x]; //维护核心代码,由于路径压缩,其到父亲距离不一定为1; father[x]=j; } return father[x]; } int main() { int i,x,y,r1,r2,r; char ch; for (i=1;i<=30000;++i) { father[i]=i; son[i]=1; pa[i]=0; } scanf("%d",&n); for (i=1;i<=n;++i) { scanf("%*c%c",&ch); if (ch=='M') { scanf("%d%d",&x,&y); r1=find(x); r2=find(y); pa[r2]=son[r1];//当前要合并节点到父亲距离即为son个数; son[r1]=son[r2]+son[r1]; //更新孩子数信息; father[r2]=r1; } if (ch=='C') { scanf("%d",&x); r=find(x); cout<<son[r]-pa[x]-1<<endl; } } }
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; struct hp{ int x,y; char kind; }a[2001]; int father[1501],n,m; int find(int x) { if (x!=father[x]) father[x]=find(father[x]); return father[x]; } int main() { int i,j,jdg,r1,r2,r3,r4,r5,r6,x,y,maxn,l,k,ans,kind; char set[1000]; bool f; while (scanf("%d%d",&n,&m)==2) { if ((n==1)&&(m==0)) cout<<"Player 0 can be determined to be the judge after 0 lines"<<endl; else { ans=0; maxn=0; memset(a,0,sizeof(a)); for (j=1;j<=m;++j) { scanf("%s",&set); l=strlen(set); k=0; x=0; y=0; while (set[k]>='0'&&set[k]<='9') { x=x*10+(int)(set[k])-48; k++; } kind=set[k]; k++; while (k<l) { y=y*10+(int)(set[k])-48; k++; } a[j].x=x; a[j].kind=kind; a[j].y=y; } for (i=0;i<=n-1;++i) { f=true; for (j=0;j<=3*n;++j) father[j]=j; for (j=1;j<=m;++j) { x=a[j].x; y=a[j].y; kind=a[j].kind; if ((x!=i)&&(y!=i)) { if (kind=='<') { swap(x,y); kind='>'; } r1=find(x); r2=find(y); r3=find(x+n); r4=find(y+n); r5=find(x+2*n); r6=find(y+2*n); if (kind=='=') { if ((r2==r3)||(r2==r5)) { maxn=max(maxn,j); f=false; break; } else { father[r2]=r1; father[r3]=r4; father [r5]=r6; } } if (kind=='>') { if ((r2==r5)||(r1==r2)) { maxn=max(maxn,j); f=false; break; } else { father[r3]=r2; father[r5]=r4; father[r1]=r6; } } } } if (f) { if (ans>0) { cout<<"Can not determine"<<endl; ans++; break; } if (ans==0) {ans++; jdg=i;} } } if (ans==1) cout<<"Player "<<jdg<<" can be determined to be the judge after "<<maxn<<" lines"<<endl; if (ans==0) cout<<"Impossible"<<endl; } } }
------------------------------------------------------------------------------------------------------------------------------- 感谢同机房神牛TA,Rivendile,yangfangyuan; lcomyn 2014.10.19 |