冗余路径 Redundant Paths e-DCC缩点
Posted bhllx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了冗余路径 Redundant Paths e-DCC缩点相关的知识,希望对你有一定的参考价值。
冗余路径 Redundant Paths
sol:
如果两点间存在至少两条不重复的路径,这说明他们两点在同一个边双连通分量(不存在割边)。
那么可以进行e-DCC的缩点,得到一棵树。
对于这棵树广泛意义上的叶子节点(度数为1)而言,都还至少需要一条边连向他。
那么可以贪心的一次连两个叶子节点,答案显然就是\(cnt+1>>1\)。
#include<bits/stdc++.h>
#define IL inline
#define RG register
#define DB double
#define LL long long
using namespace std;
const int N=5005;
const int M=1e4+5;
int n,m,tot,cnt,leaf,Time,head[N],bel[N],vis[N],low[N],dfn[N],bri[M<<1];
struct edgeint x,y;s[M];
struct EDGEint next,to;e[M<<1];
IL int gi()
RG int x=0,p=1; RG char ch=getchar();
while(ch<'0'||ch>'9') if(ch=='-') p=-1;ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*p;
IL void New()
tot=0;
memset(&e,0,sizeof(e));
memset(head,0,sizeof(head));
IL void make(int a,int b)
e[++tot]=(EDGE)head[a],b,head[a]=tot;
e[++tot]=(EDGE)head[b],a,head[b]=tot;
void Tarjan(int x,int fx)
RG int i,y;
dfn[x]=low[x]=++Time;
for(i=head[x];i;i=e[i].next)
if(!dfn[y=e[i].to])
Tarjan(y,x),low[x]=min(low[x],low[y]);
if(low[y]>dfn[x]) bri[i]=bri[i^1]=1;
else if(y!=fx) low[x]=min(low[x],dfn[y]);
void dfs(int x)
RG int i,y;
bel[x]=cnt,vis[x]=1;
for(i=head[x];i;i=e[i].next)
if(!vis[y=e[i].to]&&!bri[i]) dfs(y);
void dfs2(int x,int fx)
RG int i,y,fl=0;
for(i=head[x];i;i=e[i].next)
if((y=e[i].to)!=fx) fl=1,dfs2(y,x);
if(!fl) ++leaf;
int main()
RG int i,b=0;
n=gi(),m=gi(),tot=1;
for(i=1;i<=m;++i)
s[i].x=gi(),s[i].y=gi(),make(s[i].x,s[i].y);
for(i=1,Tarjan(1,0);i<=n;++i)
if(!vis[i]) ++cnt,dfs(i);
if(cnt==1) return puts("0"),0;
for(i=1,New();i<=m;++i)
if(bel[s[i].x]!=bel[s[i].y]) make(bel[s[i].x],bel[s[i].y]);
dfs2(1,0);
for(i=head[1];i;i=e[i].next) ++b;
if(b==1) ++leaf;
printf("%d\n",leaf+1>>1);
return 0;
以上是关于冗余路径 Redundant Paths e-DCC缩点的主要内容,如果未能解决你的问题,请参考以下文章
Luogu2860 [USACO06JAN]冗余路径Redundant Paths
luogu P2860 [USACO06JAN]冗余路径Redundant Paths |Tarjan
[USACO06JAN]冗余路径Redundant Paths(缩点)