uva 297(传递闭包 WF 1996)

题意:在一张有向图中输出所有的环。

思路:先用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 }
View Code

 

posted @ 2014-06-26 12:27  张小豪  阅读(168)  评论(0编辑  收藏  举报