Redundant Paths 分离的路径

Redundant Paths 分离的路径

题目描述

为了从F(1≤F≤5000)个草场中的一个走到另一个,贝茜和她的同伴们有时不得不路过一些她们讨厌的可怕的树.奶牛们已经厌倦了被迫走某一条路,所以她们想建一些新路,使每一对草场之间都会至少有两条相互分离的路径,这样她们就有多一些选择.
每对草场之间已经有至少一条路径.给出所有R(F-1≤R≤10000)条双向路的描述,每条路连接了两个不同的草场,请计算最少的新建道路的数量, 路径由若干道路首尾相连而成.两条路径相互分离,是指两条路径没有一条重合的道路.但是,两条分离的路径上可以有一些相同的草场. 对于同一对草场之间,可能已经有两条不同的道路,你也可以在它们之间再建一条道路,作为另一条不同的道路.

输入格式

第1行输入F和R,接下来R行,每行输入两个整数,表示两个草场,它们之间有一条道路.

输出格式

最少的需要新建的道路数.

首先我们容易得出一个结论,环上任意两点都有两条分离路径

然后我们如果将这个图缩点后将会得到一个新图,(先缩点为敬)

我们需要添加路径使变成边双连通图,边双连通图上每一条边都一定在一个环内,我们让每两个叶子节点连边使它构成环就行了。

那么问题就变成了求叶子节点个数。

然后如果叶子数为奇数我们需要再将这个点与任意一个点相连。(叶子+1)/2就完了

如果为偶数直接就是(叶子)/2

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define A 2000000
 4 #define read(a) scanf("%lld",&a)
 5 #define put(a) printf("%lld\n",a)
 6 using namespace std;
 7 map<pair<ll,ll>,bool> mp;
 8 ll low[A],size[A],dfn[A],head[A],ver[A],nxt[A],cut[A],ans[A],sz[A];
 9 ll ver2[A],nxt2[A],head2[A],out[A],belong[A],sta[A],ru[A],sb=0;
10 string s;
11 bool ins[A],flag[A],via[A];
12 vector<ll> scc[A];
13 ll n,m,num=0,root,top=0,tot=0,tot2=0,sum=0,cnt=0;
14 void add2(ll x,ll y){
15     ver2[++tot2]=y;nxt2[tot2]=head2[x];head2[x]=tot2;out[x]++;ru[y]++;return ;
16 }
17 void add(ll x,ll y){
18     ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;return ;
19 }
20 inline void rebuilt(){
21     for(ll i=1;i<=n;i++){
22         for(ll j=head[i];j;j=nxt[j]){
23             ll y=ver[j];
24             if(y!=i)
25             if(belong[i]!=belong[y]/*&&*/)
26                 add2(belong[i],belong[y])/*,,,printf("belong i=%lld,belong y=%lld\n",belong[i],belong[y])*/;
27         }
28     }
29 }
30 void tarjan(ll x,ll pre){
31     low[x]=dfn[x]=++num;
32     sta[++top]=x;ins[x]=1;
33     for(ll i=head[x];i;i=nxt[i]){
34         ll y=ver[i];
35         if(y==pre) continue;
36         if(!dfn[y]){
37             tarjan(y,x);
38             low[x]=min(low[x],low[y]);
39         }
40         else if(ins[y]){
41             low[x]=min(low[x],dfn[y]);
42         }
43     }
44     if(dfn[x]==low[x]){
45         ++cnt;ll yy=0;
46         while(1){
47             yy=sta[top--];
48             ins[yy]=0;
49             belong[yy]=cnt;
50             sz[cnt]++;
51             scc[cnt].push_back(yy);
52             if(yy==x) break;
53         }
54     }
55 }
56 void shuchu()
57 {
58         for(ll i=1;i<=cnt;i++)
59         {
60 //            printf("第%lld个scc  size=%lld\n",i,sz[i]);
61             for(ll j=0;j<scc[i].size();j++)
62             {
63                 cout<<scc[i][j]<<" ";
64             }
65             cout<<endl;
66         }
67 }
68 void dfs(ll x){
69     flag[x]=1;if(ru[x]==1) sb++;
70     for(ll i=head2[x];i;i=nxt2[i]){
71 
72         ll y=ver2[i];//        printf("x=%lld y=%lld outx=%lld\n",x,y,out[x]);
73         if(flag[y]) continue;
74         dfs(y);
75     }
76 }
77 int main(){
78         read(n);read(m);
79         for(ll i=1;i<=m;i++){
80             ll xx,yy;read(xx),read(yy);
81             if(!mp[make_pair(xx,yy)]&&!mp[make_pair(yy,xx)])
82             {
83                 add(xx,yy);add(yy,xx);mp[make_pair(xx,yy)]=1,mp[make_pair(yy,xx)]=1;
84             }
85         }
86         for(ll i=1;i<=n;i++)
87             if(!dfn[i])root=i,tarjan(i,0);        
88         rebuilt();
89 //        shuchu();
90         for(ll i=1;i<=cnt;i++)
91         {
92 //            printf("ru%lld=%lld\n",i,ru[i]);
93             if(ru[i]==1) sb++;
94         }
95         cout<<(sb+1)/2<<endl;
96 }
丑陋的有向图判无向图的环

猜你喜欢

转载自www.cnblogs.com/znsbc-13/p/11182979.html
今日推荐