UVa 247 Calling Circles【传递闭包】
题意:给出n个人的m次电话,问最后构成多少个环,找出所有的环
自己想的是:用map来储存人名,每个人名映射成一个数字编号,再用并查集,求出有多少块连通块,输出
可是map不熟,写不出来,而且用并查集输出的时候感觉貌似很麻烦
然后再用的传递闭包,可是判断到d[i][j]==1和d[j][i]==1,该怎么输出路径呢
于是看了lrj的代码= =
用的是一个ID(string s)函数来给名字编号,和第五章的集合栈计算机那题的办法一样
然后用dfs输出路径= =(这个要好好--好好--好好学)
最后还有初始化的时候d[i][i]=1,一个人自身本来就是一个联通块,所以应该初始化为1
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 #define mod=1e9+7; 12 using namespace std; 13 14 typedef long long LL; 15 const int INF = 0x7fffffff; 16 17 vector<string> names; 18 string s1,s2; 19 int vis[1005],d[105][105]; 20 int n,m; 21 22 23 int ID(string& s){ 24 for(int i=0;i<names.size();i++){ 25 if(names[i]==s) return i; 26 } 27 names.push_back(s); 28 return names.size()-1; 29 } 30 31 void dfs(int u){ 32 vis[u]=1; 33 for(int v=0;v<n;v++){ 34 if(!vis[v]&&d[u][v]&&d[v][u]) { 35 printf(", %s",names[v].c_str()); 36 dfs(v); 37 } 38 } 39 } 40 41 int main(){ 42 int i,j,k,kase=0; 43 while(scanf("%d %d",&n,&m)!=EOF&&n){ 44 memset(d,0,sizeof(d)); 45 memset(vis,0,sizeof(vis)); 46 names.clear(); 47 48 for(i=0;i<n;i++) d[i][i]=1; 49 50 for(i=0;i<m;i++){ 51 cin>>s1>>s2; 52 d[ID(s1)][ID(s2)]=1; 53 } 54 55 for(k=0;k<n;k++) 56 for(i=0;i<n;i++) 57 for(j=0;j<n;j++) 58 d[i][j]=d[i][j]||(d[i][k]&&d[k][j]); 59 60 if(kase > 0) printf("\n"); 61 printf("Calling circles for data set %d:\n", ++kase); 62 63 for(i=0;i<n;i++){ 64 if(!vis[i]){ 65 printf("%s",names[i].c_str()); 66 dfs(i); 67 printf("\n"); 68 } 69 } 70 } 71 return 0; 72 }
go---go---go----go---------