给你一个无向图,问至少加几条边可以使整个图变成一个双联通分量
简单图论练习= =
先缩点,ans = (度数为1的点的个数) / 2
这不是很好想的么QAQ
然后注意位运算的优先级啊魂淡!!!你个sb调了一个下午!!!
1 /************************************************************** 2 Problem: 1718 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:44 ms 7 Memory:3148 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 const int N = 5e4 + 5; 16 const int M = 1e5 + 5; 17 18 struct edge { 19 int next, to; 20 edge(int _n = 0, int _t = 0) : next(_n), to(_t) {} 21 } e[M]; 22 23 int n, m, ans; 24 int cnt, top, num, tot = 1; 25 int dfn[N], low[N], vis[N], sz[N], s[N], w[N], first[N]; 26 int mp[N]; 27 28 inline void Add_Edges(int x, int y) { 29 e[++tot] = edge(first[x], y), first[x] = tot; 30 e[++tot] = edge(first[y], x), first[y] = tot; 31 } 32 33 void DFS(int p, int from) { 34 dfn[p] = low[p] = ++cnt; 35 s[++top] = p, vis[p] = 1; 36 #define y e[x].to 37 register int x; 38 for (x = first[p]; x; x = e[x].next) 39 if (x != (from ^ 1)) { 40 if (!vis[y]) DFS(y, x); 41 if (vis[y] < 2) low[p] = min(low[p], low[y]); 42 } 43 #undef y 44 if (dfn[p] == low[p]) { 45 register int y; 46 ++num; 47 while (s[top + 1] != p) { 48 y = s[top--]; 49 vis[y] = 2, w[y] = num; 50 ++sz[num]; 51 } 52 } 53 } 54 55 inline void tarjan() { 56 int i; 57 cnt = top = num = 0; 58 memset(vis, sizeof(vis), 0); 59 for (i = 1; i <= n; ++i) 60 if (!vis[i]) DFS(i, 0); 61 } 62 63 int main() { 64 int i, x, y; 65 scanf("%d%d", &n, &m); 66 for (i = 1; i <= m; ++i) { 67 scanf("%d%d", &x, &y); 68 Add_Edges(x, y); 69 } 70 tarjan(); 71 #define y e[x].to 72 memset(mp, 0, sizeof(mp)); 73 for (i = 1; i <= n; ++i) 74 for (x = first[i]; x; x = e[x].next) 75 if (w[i] != w[y]) ++mp[w[y]]; 76 for (ans = i = 1; i <= num; ++i) 77 ans += (mp[i] == 1); 78 printf("%d\n", ans >> 1); 79 #undef y 80 return 0;
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen