边双连通分量模板题
Posted cutemush
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了边双连通分量模板题相关的知识,希望对你有一定的参考价值。
1:POJ3353 Road Construction
此题没有重边
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1010 #define M 2020 using namespace std; struct KSD { int v,next; }e[M]; int head[N],cnt; inline void add(int u,int v) { e[++cnt].v=v; e[cnt].next=head[u]; head[u]=cnt; } int dfn[N],low[N],n,m; int id[N],group,d[N]; int ans,edges; // 边-双个数、 桥个数 int stk[N],top; void tarjan(int x,int p) // 边双连通分量,即无桥。 { int i,v,temp; dfn[x]=low[x]=++cnt; stk[++top]=x; for(i=head[x];i;i=e[i].next) { v=e[i].v; if(v==p)continue; if(!dfn[v]) { tarjan(v,x); low[x]=min(low[x],low[v]); } else low[x]=min(low[x],dfn[v]); // if(dfn[x]<low[v])edges++; // 桥的数目 } if(dfn[x]==low[x]) { group++; do{ temp=stk[top--]; id[temp]=group; //第temp个点属于第group个连通块 }while(temp!=x); } return ; } int main() { // freopen("test.in","r",stdin); int i,j,k; int a,b,c; while(scanf("%d%d",&n,&m)!=EOF) { memset(head,0,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(d,0,sizeof(d)); cnt=group=ans=0; for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); add(a,b),add(b,a); } cnt=0; for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0); for(j=1;j<=n;j++) for(i=head[j];i;i=e[i].next) if(id[j]!=id[e[i].v]) //有一条边从J-->e[i].v //e[i].v的入度加1 d[id[e[i].v]]++; for(i=1;i<=n;i++) if(d[i]==1) ans++; printf("%d ",(ans+1)>>1); } return 0; }
以上是关于边双连通分量模板题的主要内容,如果未能解决你的问题,请参考以下文章