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 }

uva 297(传递闭包 WF 1996)

时间: 2024-10-12 05:45:57

uva 297(传递闭包 WF 1996)的相关文章

UVA 297 Quadtrees(四叉树建树、合并与遍历)

<span style="font-size: 18pt; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">K - </span><span style="color: blue; font-size: 18pt; font-family: Arial, Helvetica, sans-serif; background-color

uva 297 - Quadtrees

 Quadtrees  A quadtree is a representation format used to encode images. The fundamental idea behind the quadtree is that any image can be split into four quadrants. Each quadrant may again be split in four sub quadrants, etc. In the quadtree, the im

UVa 247 (传递闭包) Calling Circles

题意: 有n个人m通电话,如果有两个人相互打电话(直接或间接)则在同一个电话圈里.输出所有电话圈的人的名单. 分析: 根据打电话的关系,可以建一个有向图,然后用Warshall算法求传递闭包. 最后输出是辅助一个标记数组,用DFS输出的,这个办法挺巧妙的. 本来我原来的想法是,用并查集求所有的连通分量,然后再好多次循环找连通分量一致的名字输出,那样太麻烦了. ios::sync_with_stdio(false);这个最好不要随便用,可能会产生某些副作用. 字符指针是可以传给string对象作参

Quadtrees UVA 297

说说: 先来说说题意,题目给定了一个32*32大小(相当于1024个1*1的小正方形合成)的正方形,如下图所示: 其实每个大正方形可以看成一个树根,它由四个小正方形组成,四个小正方形为孩子.当然,我们可以立即给小正方形上色,黑色或白色,还可以把小正方形再细分成更小的四个正方形,直至正方形的大小为1*1为止.现在题目给你两个字符串,例如: ppeeefpffeefe pefepeefe 其中p表示该节点不是叶子节点,e表示为白色的叶子节点,f为黑色的叶子节点.整个字符串是先序遍历的结果.要求求出两

UVa 297 Quadtrees(四分树)

题意  可以用一个四分图表示一32*32的黑白图像   求两个四分树对应图像相加所得图形黑色部分有多少像素 直接用一个32*32的矩阵表示图  黑色为非0白色为0  递归建图   最后有多少个非零就是答案了 #include<cstdio> #include<cstring> using namespace std; const int L = 32, N = 1050; char s[N]; int ans[L][L], cnt; void draw(char *s, int &

UVA - 297 Quadtrees (四分树)

题意:求两棵四分树合并之后黑色像素的个数. 分析:边建树边统计. #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #inclu

UVa 297

#include <cstdio> #include <cstring> const int len = 32; const int maxn = 1024 + 10; char s[maxn]; int buf[len][len], cnt; void draw(const char* s, int& p, int r, int c, int w) { char ch = s[p++]; if(ch == 'p') { draw(s, p, r, c+w/2, w/2);

uva 297 quadtrees——yhx

Quadtrees  A quadtree is a representation format used to encode images. The fundamental idea behind the quadtree is that any image can be split into four quadrants. Each quadrant may again be split in four sub quadrants, etc. In the quadtree, the ima

UVa 297.Quadtrees【非二叉树之四分树】【7月31】

Quadtrees A quadtree is a representation format used to encode images. The fundamental idea behind the quadtree is that any image can be split into four quadrants. Each quadrant may again be split in four sub quadrants, etc. In the quadtree, the imag