题目描述
Description
1920年的芝加哥,出现了一群强盗。如果两个强盗遇上了,那么他们要么是朋友,要么是敌人。而且有一点是肯定的,就是:
我朋友的朋友是我的朋友;
我敌人的敌人也是我的朋友。
两个强盗是同一团伙的条件是当且仅当他们是朋友。现在给你一些关于强盗们的信息,问你最多有多少个强盗团伙。
输入描述
Input Description
输入文件gangs.in的第一行是一个整数N(2<=N<=1000),表示强盗的个数(从1编号到N)。 第二行M(1<=M<=5000),表示关于强盗的信息条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敌人。输入数据保证不会产生信息的矛盾。
输出描述
Output Description
输出文件gangs.out只有一行,表示最大可能的团伙数。
样例输入
Sample Input
6
4
E 1 4
F 3 5
F 4 6
E 1 2
样例输出
Sample Output
3
数据范围及提示
Data Size & Hint
2<=N<=1000
1<=M<=5000
1<=p q<=N
分类标签 Tags 点此展开
超时代码(递归时间太长了吧大概是因为):
(温馨贴士:递归能不用则不用)
1 #include<iostream> 2 #include<cstdio> 3 #define Maxn 1005 4 5 using namespace std;//(F为朋友E为敌人) 6 7 int f1,f2,n,m,tot=0; 8 int F[Maxn],e[Maxn]; 9 bool vis[Maxn]; 10 11 int find(int x) 12 { 13 return x == F[x] ? x : F[x]=find(F[x]); 14 } 15 16 void unionn(int x,int y) 17 { 18 f1=find(x); 19 f2=find(y); 20 if(f1!=f2) 21 { 22 F[f1]=f2; 23 if(e[f2]!=0)//合并时,若r2有敌人 24 { 25 unionn(e[f2],f1); 26 if(e[f1]!=0)//若r1也有敌人 27 { 28 unionn(e[f1],e[f2]);//则它们的敌人是朋友 29 } 30 else e[f1]=e[f2];//否则,r2的敌人同时也是r1的敌人,即他们为朋友 31 } 32 } 33 } 34 35 int main() 36 { 37 char p; 38 int x,y; 39 scanf("%d%d",&n,&m); 40 for(int i=1;i<=n;i++)//初始化 41 { 42 F[i]=i; 43 e[i]=0; 44 } 45 for(int i=1;i<=m;i++) 46 { 47 cin>>p>>x>>y; 48 if(p=='F') //if x is y's friend 49 { 50 unionn(x,y); //并在一起 51 } 52 if(p=='E') //if x is y's 敌人(英语不会哈) 53 { 54 x=find(x); 55 if(e[x]==0)//将y作为x团伙的敌人 56 { 57 e[x]=y; 58 }else unionn(e[x],y); 59 if(e[y]==0)//与之类似 60 { 61 e[y]=x; 62 }else unionn(e[y],x); 63 } 64 } 65 for(int i=1;i<=n;i++) 66 { 67 if(find(i)==i) tot++;//进行统计 68 } 69 printf("%d\n",tot); 70 return 0; 71 }
AC代码:
其实就是把递归的地方改掉了而已,要好好的进行理解!!!
1 #include<iostream> 2 #include<cstdio> 3 #define Maxn 2333 4 5 using namespace std;//(F为朋友E为敌人) 6 7 int f1,f2,n,m,tot=0; 8 int F[Maxn],e[Maxn]; 9 10 int find(int x) 11 { 12 return x == F[x] ? x : F[x]=find(F[x]); 13 } 14 15 int main() 16 { 17 char p; 18 int x,y; 19 scanf("%d%d",&n,&m); 20 for(int i=1;i<=n;i++)//初始化 21 { 22 F[i]=i; 23 } 24 for(int i=1;i<=m;i++) 25 { 26 cin>>p>>x>>y; 27 if(p=='F') //if x is y's friend 28 { 29 f1=find(x);f2=find(y); 30 if(f1!=f2) F[f1]=f2; //并在一起 31 } 32 if(p=='E') //if x is y's 敌人(英语不会哈) 33 { 34 e[x] ? F[find(e[x])] = find(y) : e[x]=y;//x有敌人么?有就将y的集团与x敌人的集团并起来,没有就将y作为x的敌人 35 e[y] ? F[find(e[y])] = find(x) : e[y]=x;//同上 36 } 37 } 38 for(int i=1;i<=n;i++) 39 { 40 if(find(i)==i) tot++;//进行统计 41 } 42 printf("%d\n",tot); 43 return 0; 44 }