您的位置:首页 > 其它

poj 3177 Redundant Paths (双连…

2013-04-23 09:26 330 查看
题意:有F个农场 有R条路把它们相连(当然是无向的) 要求加多少条边,使得每两个农场之间起码有两条不同的路径

思路:求无向图的边双连通 缩点后,求出叶子结点的个数 加1 除2 就是要加的边 (这是个定理,这里就不证明了)

//
268K
0MS

#include <stdio.h>

#include <string.h>

#define VM 5010

#define EM 10010

struct E

{

int
to,nxt;

}edge[2*EM];

int head[VM],vis[VM],dfn[VM],low[VM];

int n,e,cnt;

void addedge (int cu,int cv)

{

edge[e].to =
cv;

edge[e].nxt
= head[cu];

head[cu] = e
++;

}

int min (int a,int b)

{

return a
> b ? b : a;

}

void dfs (int u,int
fa)
//Tarjan

{

vis[u] =
1;

dfn[u] =
low[u] = ++cnt;

for (int i =
head[u];i != -1;i = edge[i].nxt)

{

int v = edge[i].to;

if (vis[v] == 1&& v != fa)

low[u] = min (low[u],dfn[v]);

if (vis[v] == 0)

{

dfs (v,u);

low[u] = min (low[u],low[v]);

}

}

vis[u] =
2;

}

int main ()

{

int
m,i,u,v;

int
deg[VM];

while
(~scanf ("%d%d",&n,&m))

{

memset (head,0xFF,sizeof (head));

memset (vis,0,sizeof(vis));

memset (dfn,0,sizeof(dfn));

memset (low,0,sizeof(low));

memset (deg,0,sizeof(deg));

e = 0;

while (m -- )

{

scanf ("%d%d",&u,&v);

if (head[u]!= -1 &&edge[head[u]].to
== v)
//注意有重边,加判断去掉重边

continue;

addedge (u,v);

addedge (v,u);

}

cnt = 0;

dfs (1,1);

for (u = 1;u <= n;u ++)

{

for (i = head[u];i != -1;i = edge[i].nxt)

{

v = edge[i].to;

if (low[u] != low[v])

deg[low[u]]
++;
//算出缩点后每个点的度

}

}

int left = 0;

for (i = 1;i <= n;i ++)

if (deg[i] ==
1) //度为1
的为叶子结点

left ++;

printf ("%d\n",(left+1)/2);

}

return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: