旅游航道
作者:互联网
题目描述
给出一张旅游航线(双向),定义主要航道为删除后使一些点不能到达的边,求给定图中主要航道的数量。
思路
其实就是给出一张图求图中桥的数量。考虑tarjan的过程中,如果low[v]>dfn[u],那么这条边就是桥,因为从这条边无法再到达dfs序更小的点,不过访问的时候需要考虑这条边不是已访问过的树枝边。
代码
#include <bits/stdc++.h> using namespace std; const int N=33000,M=N<<1; int read() { int res=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();} return res*w; } int nxt[M],to[M],tot,head[N]; void add_edge(int x,int y) { nxt[tot]=head[x]; head[x]=tot; to[tot]=y; ++tot; } int dfn[N],low[N],from[N],idx; bool cut[M]; void tarjan(int u) { dfn[u]=low[u]=++idx; for(int i=head[u];~i;i=nxt[i]) { if(i==(from[u]^1))continue ; int v=to[i]; if(!dfn[v]) { from[v]=i; tarjan(v); low[u]=min(low[u],low[v]); if(low[v]>dfn[u])cut[from[v]]=cut[from[v]^1]=1; } else low[u]=min(low[u],dfn[v]); } } void clear() { memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(cut,0,sizeof(cut)); memset(from,0,sizeof(from)); tot=0;idx=0; } int main() { int m,n; while(~scanf("%d%d",&m,&n)&&(m|n)) { clear(); for(int i=1;i<=n;i++) { int x=read(),y=read(); add_edge(x,y);add_edge(y,x); } for(int i=1;i<=m;i++) if(!dfn[i])tarjan(i); int cnt=0; for(int i=0;i<n*2;i++) if(cut[i])cnt++; printf("%d\n",cnt/2); } }
标签:cut,int,memset,航道,ch,dfn,旅游,sizeof 来源: https://www.cnblogs.com/fangbozhen/p/11741058.html