2014-09-10 16:25:06
思路:有点逗的一题,给出有向图,让你找环并输出,由于数据范围小,用DFS乱搞感觉也能行。这里用Floyd判一下有向图的传递闭包,就当加强理论把。过程就是用Floyd霸气地松弛全图,i 点和 j 点连通就令d[i][j] = 1,不连通令为0。若d[i][j] = d[j][i] = 1,则说明 i、j 两点在同个环内。输出递归 / 循环随意。
1 /************************************************************************* 2 > File Name: 247.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 10 Sep 2014 04:04:22 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 typedef long long ll; 18 const int INF = 1 << 29; 19 20 int d[30][30]; 21 int n,m,cnt,Case; 22 char name[30][30]; 23 24 void Floyd(){ 25 for(int k = 1; k <= n; ++k) 26 for(int i = 1; i <= n; ++i) 27 for(int j = 1; j <= n; ++j){ 28 d[i][j] = d[i][j] || (d[i][k] && d[k][j]); 29 } 30 } 31 32 void Init(){ 33 cnt = 0; 34 memset(d,0,sizeof(d)); 35 } 36 37 void Print(){ 38 int vis[30] = {0}; 39 if(Case) puts(""); 40 printf("Calling circles for data set %d:\n",++Case); 41 for(int i = 1; i <= n; ++i) if(!vis[i]){ 42 printf("%s",name[i]); 43 vis[i] = 1; 44 for(int j = 1; j <= n; ++j) if(!vis[j] && d[i][j] && d[j][i]){ 45 printf(", %s",name[j]); 46 vis[j] = 1; 47 } 48 puts(""); 49 } 50 51 } 52 53 int main(){ 54 char n1[30],n2[30]; 55 while(scanf("%d%d",&n,&m) != EOF && (n || m)){ 56 Init(); 57 for(int i = 1; i <= m; ++i){ 58 scanf("%s%s",n1,n2); 59 int x = 0,y = 0; 60 for(int j = 1; j <= cnt; ++j) if(strcmp(name[j],n1) == 0) 61 x = j; 62 for(int j = 1; j <= cnt; ++j) if(strcmp(name[j],n2) == 0) 63 y = j; 64 if(x == 0) strcpy(name[++cnt],n1),x = cnt; 65 if(y == 0) strcpy(name[++cnt],n2),y = cnt; 66 d[x][y] = 1; 67 } 68 Floyd(); 69 Print(); 70 } 71 return 0; 72 }