标签:include void continue highlight else dfs str || from
找出所有的桥出来,然后去掉桥即可
#include<cstdio> #include<iostream> using namespace std; const int MAXN=1e5,MAXM=1e6; struct Edge{ int from,to,nxt; }e[MAXM]; int head[MAXN],edgeCnt=1; void addEdge(int u,int v) { e[++edgeCnt].from=u; e[edgeCnt].to=v; e[edgeCnt].nxt=head[u]; head[u]=edgeCnt; } int dfn[MAXN],low[MAXN],dfnCnt=0; bool bridge[MAXM]; void tarjan(int x,int in_edge) { dfn[x]=low[x]=++dfnCnt; for(int i=head[x];i;i=e[i].nxt) { int nowV=e[i].to; if(!dfn[nowV]) { tarjan(nowV,i); if(low[nowV]>dfn[x]) { bridge[i]=bridge[i^1]=1; } low[x]=min(low[x],low[nowV]); } else if(i!=(in_edge^1)) { low[x]=min(low[x],dfn[nowV]); } } } int inDcc[MAXN]; void dfs(int x,int nowDcc) { inDcc[x]=nowDcc;//将X点归入nowdcc这个边双中 for(int i=head[x];i;i=e[i].nxt) { int nowV=e[i].to; if(inDcc[nowV]||bridge[i]) //如果已归到某个边双,或第I条边是桥的话 continue; dfs(nowV,nowDcc); } } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); addEdge(u,v); addEdge(v,u); } for(int i=1;i<=n;i++) //找出所有的桥出来 if(!dfn[i]) tarjan(i,0); int nowDcc=0; for(int i=1;i<=n;i++) //如果i点还没有归到某个边双 if(!inDcc[i]) dfs(i,++nowDcc); printf("%d\n",nowDcc); return 0; }
标签:include void continue highlight else dfs str || from
原文地址:https://www.cnblogs.com/cutemush/p/12681811.html