hdu 3172+hdu 3635+hdu 3926
来源:互联网 发布:安卓数据库 编辑:程序博客网 时间:2024/05/18 15:56
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3172
思路:将名字转化为对应的序号就可以,然后就是基本的并查集操作了。。。
View Code
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<map> 6 #include<string> 7 using namespace std; 8 const int MAXN=100000+10; 9 int parent[MAXN];10 int n,num;11 12 int Find(int x){13 int s;14 for(s=x;parent[s]>=0;s=parent[s]);15 while(s!=x){16 int tmp=parent[x];17 parent[x]=s;18 x=tmp;19 }20 return s;21 }22 23 void Union(int R1,int R2){24 int r1=Find(R1);25 int r2=Find(R2);26 if(r1==r2)return ;27 if(parent[r1]>parent[r2]){28 parent[r1]+=parent[r2];29 parent[r2]=r1;30 }else {31 parent[r2]+=parent[r1];32 parent[r1]=r2;33 }34 }35 36 37 38 int main(){39 int _case;40 while(~scanf("%d",&_case)){41 while(_case--){42 scanf("%d",&n);43 num=1;44 map<string,int>mp;45 46 for(int i=1;i<=n;i++){47 char s1[22],s2[22];48 scanf("%s%s",s1,s2);49 if(mp.find(s1)==mp.end()){50 parent[num]=-1;51 mp[s1]=num++;52 }53 if(mp.find(s2)==mp.end()){54 parent[num]=-1;55 mp[s2]=num++;56 }57 Union(mp[s1],mp[s2]);58 int rt=Find(mp[s1]);59 printf("%d\n",abs(parent[rt]));60 }61 }62 }63 return 0;64 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3635
思路:这题的关键之处在于如何求出转移次数。。。其实我们可以在Find()函数中添加一个—_count[]数组来保存每次转移的次数,具体见代码:
View Code
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 const int MAXN=10000+10; 7 int parent[MAXN]; 8 int _count[MAXN]; 9 int Rank[MAXN];10 int n,m;11 12 void Initiate(){13 for(int i=1;i<=n;i++){14 parent[i]=i;15 _count[i]=0;16 Rank[i]=1;17 }18 }19 20 int Find(int x){21 if(x==parent[x])return x;22 else {23 int tmp=parent[x];24 parent[x]=Find(parent[x]);25 _count[x]+=_count[tmp];//更新转移次数26 }27 return parent[x];28 }29 30 31 void Union(int R1,int R2){32 int r1=Find(R1);33 int r2=Find(R2);34 if(r1==r2)return ;35 else {36 parent[r1]=r2;37 _count[r1]++;38 Rank[r2]+=Rank[r1];39 Rank[r1]=0;40 }41 }42 43 44 int main(){45 int _case,t=1;46 scanf("%d",&_case);47 while(_case--){48 scanf("%d%d",&n,&m);49 Initiate();50 printf("Case %d:\n",t++);51 for(int i=1;i<=m;i++){52 char str[11];53 scanf("%s",str);54 if(str[0]=='T'){55 int u,v;56 scanf("%d%d",&u,&v);57 Union(u,v);58 }else if(str[0]=='Q'){59 int x;60 scanf("%d",&x);61 int y=Find(x);62 printf("%d %d %d\n",y,Rank[y],_count[x]);63 }64 }65 }66 return 0;67 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926
思路:判断两个图是否同构:
首先当然是并查集的一些基本操作了,不过合并的时候应该遵循孩子节点少的合并到孩子节点多的集合中(不然wa),然后就是排序后比较一下就可以了(因为图可能存在环,因此可以先按孩子节点的个数排,然后再按是否存在环排);
View Code
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int MAXN=10000+10; 8 int n1,m1,n2,m2; 9 int parent1[MAXN],parent2[MAXN]; 10 struct Graph{ 11 int child; 12 bool ring;//false代表成链,true代表成环 13 }; 14 Graph g1[MAXN],g2[MAXN]; 15 16 void Initiate(){ 17 for(int i=1;i<=n1;i++){ 18 parent1[i]=-1; 19 parent2[i]=-1; 20 g1[i].child=1; 21 g2[i].child=1; 22 g1[i].ring=false; 23 g2[i].ring=false; 24 } 25 } 26 27 int Find(int x,int parent[]){ 28 int s; 29 for(s=x;parent[s]>=0;s=parent[s]); 30 while(s!=x){ 31 int tmp=parent[x]; 32 parent[x]=s; 33 x=tmp; 34 } 35 return s; 36 } 37 38 39 40 void Union(int R1,int R2,int parent[],Graph g[]){ 41 int r1=Find(R1,parent); 42 int r2=Find(R2,parent); 43 if(r1==r2){ 44 g[r1].ring=true;//根结点相同,说明存在环 45 }else { 46 if(g[r1].child>=g[r2].child){ 47 parent[r2]=r1; 48 g[r1].child+=g[r2].child; 49 }else { 50 parent[r1]=r2; 51 g[r2].child+=g[r1].child; 52 } 53 } 54 } 55 56 int cmp(const Graph &g1,const Graph &g2){ 57 if(g1.child!=g2.child){ 58 return g1.child<g2.child; 59 } 60 return g1.ring<g2.ring;//先链后环 61 } 62 63 bool Solve(){ 64 sort(g1+1,g1+n1+1,cmp); 65 sort(g2+1,g2+n2+1,cmp); 66 for(int i=1;i<=n1;i++){ 67 if(g1[i].child!=g2[i].child||(g1[i].child==g2[i].child&&g1[i].ring!=g2[i].ring)) 68 return false; 69 } 70 return true; 71 } 72 73 74 75 int main(){ 76 int _case,t=1; 77 scanf("%d",&_case); 78 while(_case--){ 79 scanf("%d%d",&n1,&m1); 80 Initiate(); 81 bool flag=true; 82 for(int i=1;i<=m1;i++){ 83 int u,v; 84 scanf("%d%d",&u,&v); 85 Union(u,v,parent1,g1); 86 } 87 scanf("%d%d",&n2,&m2); 88 if(m1!=m2||n1!=n2){ 89 flag=false; 90 } 91 for(int i=1;i<=m2;i++){ 92 int u,v; 93 scanf("%d%d",&u,&v); 94 if(!flag)continue; 95 Union(u,v,parent2,g2); 96 } 97 printf("Case #%d: ",t++); 98 if(!flag){ 99 printf("NO\n");100 }else {101 flag=Solve();102 if(flag){103 printf("YES\n");104 }else 105 printf("NO\n");106 }107 }108 return 0;109 }110 111
0 0
- hdu 3172+hdu 3635+hdu 3926
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- hdu 1181(并查集+拓扑排序)
- 应用程序与内核模块的比较
- hdu 1829+hdu 1856(并查集)
- 几种算法的C实现
- hdu 2473
- hdu 3172+hdu 3635+hdu 3926
- hdu 1050+hdu 1789+hdu 3177(贪心)
- whu 1478(模拟链表)
- hdu 1172(模拟、枚举)
- hdu 1237(模拟栈、水题)
- hdu 1296(多项式模拟)
- hdu 1302(简单模拟题)
- hdu 2832(数学题)
- hdu 1306(字符串匹配)