题意:在一张有向图中输出所有的环。
思路:先用Floyd求传递闭包,然后通过传递闭包建图若是Map[i][j] && Map[j][i]则建一条无向边。然后图中所有的连通分支即为一个环。
代码如下:
1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-06-26 11:12 5 * Filename : uva_247.cpp 6 * Description : 7 * ************************************************/ 8 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <cmath> 14 #include <algorithm> 15 #include <queue> 16 #include <stack> 17 #include <vector> 18 #include <set> 19 #include <map> 20 #define MP(a, b) make_pair(a, b) 21 #define PB(a) push_back(a) 22 23 using namespace std; 24 typedef long long ll; 25 typedef pair<int, int> pii; 26 typedef pair<unsigned int,unsigned int> puu; 27 typedef pair<int, double> pid; 28 typedef pair<ll, int> pli; 29 typedef pair<int, ll> pil; 30 31 const int INF = 0x3f3f3f3f; 32 const double eps = 1E-6; 33 const int LEN = 1010; 34 vector<int> Map[LEN], ans[LEN]; 35 map<string, int> mp; 36 string a, b, name[LEN]; 37 int n, m, top, cnt, Mp[LEN][LEN], vis[LEN]; 38 39 int ch(string a){ 40 if(!mp.count(a)) { 41 name[top] = a; 42 mp[a] = top++; 43 } 44 return mp[a]; 45 } 46 47 void Floyd(){ 48 for(int k=0; k<n; k++){ 49 for(int i=0; i<n; i++){ 50 for(int j=0; j<n; j++){ 51 if(Mp[i][j] || (Mp[i][k] && Mp[k][j])) { 52 Mp[i][j] = 1; 53 } 54 } 55 } 56 } 57 } 58 59 void dfs(int v, int tag){ 60 vis[v] = tag; 61 for(int i=0; i<Map[v].size(); i++){ 62 int x = Map[v][i]; 63 if(vis[x] < 0) dfs(x, tag); 64 } 65 } 66 67 void solve(){ 68 for(int i=0; i<n; i++){ 69 for(int j=0; j<n; j++){ 70 if(Mp[i][j] && Mp[j][i]){ 71 Map[i].PB(j); 72 Map[j].PB(i); 73 } 74 } 75 } 76 cnt = 0; 77 memset(vis, -1, sizeof vis); 78 for(int i=0; i<n; i++){ 79 if(vis[i] < 0) dfs(i, cnt++); 80 } 81 for(int i=0; i<cnt; i++){ 82 for(int j=0; j<n; j++){ 83 if(vis[j] == i){ 84 ans[i].PB(j); 85 } 86 } 87 } 88 } 89 90 void out(int &kase){ 91 if(kase != 1) cout << endl; 92 cout << "Calling circles for data set "<< kase++ << ":" << endl; 93 for(int i=0; i<cnt; i++){ 94 for(int j=0; j<ans[i].size(); j++){ 95 cout << name[ans[i][j]]; 96 if(j != ans[i].size()-1)cout << ", "; 97 } 98 cout << endl; 99 } 100 } 101 102 int main() 103 { 104 // freopen("in.txt", "r", stdin); 105 106 ios::sync_with_stdio(false); 107 int kase = 1; 108 while(cin >> n >> m){ 109 if(!n && !m) break; 110 memset(Mp, 0, sizeof Mp); 111 for(int i=0; i<LEN; i++) Map[i].clear(); 112 for(int i=0; i<LEN; i++) ans[i].clear(); 113 mp.clear();top = 0; 114 for(int i=0; i<m; i++){ 115 cin >> a >> b; 116 int na = ch(a), nb = ch(b); 117 Mp[na][nb] = 1; 118 } 119 Floyd(); 120 solve(); 121 out(kase); 122 } 123 return 0; 124 }