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 }