poj 3352 Road Construction 边双连通缩点

来源:互联网 发布:java反序列化漏洞利用 编辑:程序博客网 时间:2024/06/13 06:50

题意:给你一个图,问至少需要加多少条路使得整个图成为边双连通。


求出割边并缩点,可以得到一棵树,统计树上所有度为1的点数,最后的答案就是(cnt+1)/2,这个画个图就明白了。

ps:这题坑了我两个wa,输入和输出原来不需要Sample Input 1。。太坑了

#include <stdio.h>#include <string.h>const int maxn = 1002;const int maxm = 1005;struct EDGE{int to, next, vis;}edge[maxm<<1];int head[maxn], dfn[maxn], belo[maxn], low[maxn], st[maxn];int E, time, top, gtot, type;struct GEDGE{int u, to;}gedge[maxm];void newedge(int u, int to) {edge[E].to = to;edge[E].next = head[u];edge[E].vis = 0;head[u] = E++;}void init() {memset(head, -1, sizeof(head));memset(dfn, 0, sizeof(dfn));memset(belo, 0, sizeof(belo));E = time = type = top = gtot = 0;}int min(int a, int b) {return a > b ? b : a;}void dfs(int u) {dfn[u] = low[u] = ++time;st[++top] = u;for(int i = head[u];i != -1;i = edge[i].next) {if(edge[i].vis)continue;edge[i].vis = edge[i^1].vis = 1;int to = edge[i].to;if(!dfn[to]) {dfs(to);low[u] = min(low[u], low[to]);if(low[to] > dfn[u]) {type++;int v;do {v = st[top--];belo[v] = type;} while(v != to);gedge[gtot].u = u;gedge[gtot++].to = to; }}elselow[u] = min(low[u], low[to]);}}int ans ;void DFS(int u, int pre) {int tot = 0;if(pre != -1)tot++;for(int i = head[u];i != -1;i = edge[i].next) {int to = edge[i].to;if(to != pre) {DFS(to, u);tot++;}}if(tot == 1)ans++;}char s[111];int main() {int n, m, i, u, to;while(scanf("%d%d", &n, &m) != -1) {init();for(i = 0;i < m;i ++) {scanf("%d%d", &u, &to);newedge(u, to);newedge(to, u);}for(i = 1;i <= n; i++) if(!dfn[i])dfs(i);memset(head, -1, sizeof(head));E = 0;for(i = 0;i < gtot; i++) {u = belo[gedge[i].u];to = belo[gedge[i].to];newedge(u, to);newedge(to, u);}ans = 0;DFS(0, -1);printf("%d\n", (ans+1)/2);}return 0;}


原创粉丝点击