POJ3177 分离的路径

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3177 分离的路径相关的知识,希望对你有一定的参考价值。

题目大意:

  有 F个牧场,现在一个牧群经常需要从一个牧场迁移到另一个牧场。奶牛们已经厌烦老 是走同一条路,

所以有必要再新修几条路,这样它们从一个牧场迁移到另一个牧场时总是可 以选择至少两条独立的路。现在 F 个

牧场的任何两个牧场之间已经至少有一条路了,奶牛们需要至少有两条。 给定现有的 R 条直接连接两个牧场的路,

计算至少需要新修多少条直接连接两个牧场的路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指

没有公共边的路,但可以经过同一个中间顶点。

1<=F<=5000 ; F-1<=R<=10000

输入格式:

  第一行两个数F,R

  接下去R行,每行两个数a,b表示a与b有一条道路

输出格式:

  至少要加入的边的数量

输入样例:

  7 7
  1 2
  2 3
  3 4
  2 5
  4 5
  5 6
  5 7

输出样例:

  2

题解:

  把一张有桥的无向图加边变成边双联通图,先求出所有的桥,把非桥的双联通图缩点,可以用并查集维护,然

后对于每个桥两端的代表点的度数加1。

  度数为1的就是缩点后的叶节点,对于每对叶节点可以用一条边使之产生环而变为双联通图,答案即为(num+1)/2。(num为叶节点的数量)

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 struct node
 8 {
 9     int next,to,fr;
10 }    e[20005];
11 int cnt=1,head[5005],time,from[5005],fa[5005],in[5005];
12 int dfn[5005],low[5005];
13 bool cut[20005];
14 inline void insert(int u,int v)
15 {
16     e[++cnt].next=head[u];
17     head[u]=cnt;
18     e[cnt].to=v;
19     e[cnt].fr=u;
20 }
21 inline int find(int x)
22 {
23     return x==fa[x]?x:fa[x]=find(fa[x]);
24 }
25 inline void tarjan(int now)
26 {
27     dfn[now]=low[now]=++time;
28     for(int i=head[now];i;i=e[i].next)
29     {
30         if(i==(from[now]^1))    continue;
31         if(!dfn[e[i].to])
32         {
33             from[e[i].to]=i;
34             tarjan(e[i].to);
35             low[now]=min(low[now],low[e[i].to]);
36             if(low[e[i].to]>dfn[now])    
37                 cut[i]=cut[i^1]=1;
38         }
39         else    low[now]=min(low[now],dfn[e[i].to]);
40     }
41 }
42 int main()
43 {
44     int n,m,u,v,num=0; 
45     scanf("%d%d",&n,&m);
46     for(int i=1;i<=m;i++)
47     {
48         scanf("%d%d",&u,&v);
49         insert(u,v);
50         insert(v,u);
51     }
52     tarjan(1);
53     for(int i=1;i<=n;i++)    fa[i]=i;
54     for(int i=2;i<=cnt;i+=2)
55         if(!cut[i])    fa[find(e[i].fr)]=find(e[i].to);
56     for(int i=2;i<=cnt;i+=2)
57         if(cut[i])    in[find(e[i].fr)]++,in[find(e[i].to)]++;
58     for(int i=1;i<=n;i++)
59         if(find(i)==i && in[i]==1)    num++;
60     printf("%d",(num+1)/2);
61 }

 

以上是关于POJ3177 分离的路径的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1718&&POJ3177Redundant Paths

poj-3177(并查集+双联通分量+Tarjan算法)

poj——3177Redundant Paths

POJ 3177 - Redundant Paths - 双连通分量

POJ 3177 Redundant Paths(强连通分量)

POJ3177 Redundant Paths