uva 610(割边)

题意:这道题很有意思。他是给你一个无向图然后让你把尽量多的边转化成单向边,然后是整张图还是强联通的。

思路:看到这道题的第一反应就是求割边,应为割边所连接的都是双连通分支对于双连通分支我们只需要化成单向边就能解决问题。然后对于割边我们才需要化成双向边。之后我就考虑了一下如何输出答案。这很容易就类似于欧拉通路我开了两个标记数组,一个标记点,另一个标记边。输出一条标记一条即可。注意不要经过桥。然后最后再把所有的桥输出就可以了。

代码如下:

 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-01-29 15:01
 5  * Filename     : uva_610.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 int n, m, dclock;
35 int bri[LEN][LEN], dfn[LEN], low[LEN], vis[LEN][LEN], vex[LEN], Map[LEN][LEN];
36 
37 void dfs(int u, int fa){
38     dfn[u] = low[u] = dclock++;
39     for(int i=1; i<=n; i++){
40         if(!Map[u][i]) continue;
41         if(dfn[i]<0){
42             dfs(i, u);
43             low[u] = min(low[u], low[i]);
44             if(dfn[u] < low[i]) bri[u][i] = bri[i][u] = 1;
45         }else if(low[u] > low[i] && i != fa)low[u] = min(low[u], dfn[i]);
46     }
47 }
48 
49 void out(int v){
50     vex[v] = 1;
51     for(int i=1; i<=n; i++){
52         if(!Map[v][i] || bri[v][i] || vis[v][i]) continue;
53         vis[v][i] = vis[i][v] = 1;
54         cout << v << ' ' << i << endl;
55         out(i);
56     }
57 }
58 
59 int main()
60 {
61 //    freopen("in.txt", "r", stdin);
62     
63     int a, b;
64     for(int kase = 1; scanf("%d%d", &n, &m)!=EOF; kase++){
65         if(!n && !m) break;
66         memset(Map, 0, sizeof Map);
67         printf("%d

", kase);
68         for(int i=0; i<m; i++){
69             scanf("%d%d", &a, &b);
70             Map[b][a] = Map[a][b] = 1;
71         }
72         dclock = 0;
73         memset(dfn, -1, sizeof dfn);
74         memset(bri, 0, sizeof bri);
75         dfs(1, -1);
76         memset(vis, 0, sizeof vis);
77         memset(vex, 0, sizeof vex);
78         for(int i=1; i<=n; i++)if(!vex[i])out(i);
79         for(int i=1; i<=n; i++){
80             for(int j=1; j<=n; j++){
81                  if(bri[i][j])cout << i << ' ' << j << endl;
82             }
83         }
84         printf("#
");
85     }
86     return 0;
87 }
View Code
奔跑吧!少年!趁着你还年轻
原文地址:https://www.cnblogs.com/shu-xiaohao/p/3536224.html