首页 > 代码库 > uva 297(传递闭包 WF 1996)

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