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