uva 12167(强连通分支)

题意:在一张有向图中最少添加几条边,能使它强连通。

思路:自己想的时候差了一点。。最后还是看了一眼白书秒过了。首先第一步很简单当然是缩点。变成DAG接下来问题就是DAG上最少添几条边使他强连通。其实只要求出max(出度为零的节点数,入度为零的结点数)。注意当原图已经强联通时特判一下。

代码如下:

uva 12167(强连通分支)
 1 /**************************************************
 2  * Author     : xiaohao Z
 3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
 4  * Last modified : 2014-01-31 22:26
 5  * Filename     : uva_12167.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 = 100000+10;
34 vector<int> Map[LEN];
35 int n, m, dclock, scc_cnt, dfn[LEN], low[LEN], sccn[LEN];
36 stack<int> s;
37 
38 void sccinit(){
39     for(int i=0; i<LEN; i++) Map[i].clear();
40     while(!s.empty()) s.pop();
41     memset(dfn, 0, sizeof dfn);
42     memset(sccn, 0, sizeof sccn);
43     dclock = scc_cnt = 0;
44 }
45 
46 void dfs(int u){
47     low[u] = dfn[u] = ++dclock;
48     s.push(u);
49     for(int i=0; i<Map[u].size(); i++){
50         int v = Map[u][i];
51         if(!dfn[v]){
52             dfs(v);
53             low[u] = min(low[u], low[v]);
54         }else if(!sccn[v]) low[u] = min(low[u], dfn[v]);
55     }
56     if(dfn[u] == low[u]){
57          scc_cnt ++;
58          while(1){
59              int x = s.top();s.pop();
60              sccn[x] = scc_cnt;
61              if(u == x) break;
62          }
63     }
64 }
65 
66 int main()
67 {
68 //    freopen("in.txt", "r", stdin);
69 
70     int T, a, b;
71     scanf("%d", &T);
72     while(T--){
73         sccinit();
74         scanf("%d%d", &n, &m);
75         for(int i=0; i<m; i++){
76             scanf("%d%d", &a, &b);
77             Map[a].PB(b);
78         }
79         int od[LEN] = {0}, id[LEN] = {0};
80         for(int i=1; i<=n; i++)if(!dfn[i])dfs(i);
81         for(int i=1; i<=n; i++){
82              for(int j=0; j<Map[i].size(); j++){
83                 if(sccn[i] == sccn[Map[i][j]]) continue;
84                 od[sccn[i]] = 1;
85                 id[sccn[Map[i][j]]] = 1;
86              }
87         }
88         a = b = 0;
89         for(int i=1; i<=scc_cnt; i++) {
90             if(!od[i]) a++;     
91             if(!id[i]) b++;
92         }
93         if(scc_cnt!=1)printf("%d\n", max(a, b));
94         else printf("0\n");
95     }
96     return 0;
97 }
View Code

uva 12167(强连通分支)

上一篇:【语法】NSDictionary数据字典


下一篇:C#字符串排序效率