poj1523割顶-点双联通
Posted walfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1523割顶-点双联通相关的知识,希望对你有一定的参考价值。
题意:求出所有的割顶,而且还有输出该割顶连接了几个点双连通分量
题解:直接tarjan求点双联通分量就好了,可以在加入边的时候记录加入次数,大于1的都是桥,输入输出很恶心,注意格式
#include<map> #include<set> #include<list> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; using namespace __gnu_cxx; const double g=10.0,eps=1e-7; const int N=1000+10,maxn=100000+10,inf=0x3f3f3f; map<int,int>ma[N]; vector<int>v[N],bcc[N]; int dfn[N],low[N]; int index,num; int bccno[N],iscut[N]; struct edge{int from,to;}; stack<edge>s; void tarjan(int u,int f) { low[u]=dfn[u]=++index; for(int i=0;i<v[u].size();i++) { int x=v[u][i]; edge e=(edge){u,x}; if(x==f)continue; if(!dfn[x]) { s.push(e); tarjan(x,u); low[u]=min(low[u],low[x]); if(low[x]>=dfn[u]) { num++;bcc[num].clear(); for(;;) { edge p=s.top();s.pop(); if(bccno[p.from]!=num) { bccno[p.from]=num; bcc[num].pb(p.from); iscut[p.from]++; } if(bccno[p.to]!=num) { bccno[p.to]=num; bcc[num].pb(p.to); iscut[p.to]++; } if(p.from==e.from&&p.to==e.to)break; } } } else { if(dfn[x]<dfn[u])low[u]=min(low[u],dfn[x]); } } } void init() { memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(bccno,0,sizeof bccno); memset(iscut,0,sizeof iscut); index=num=0; for(int i=1;i<=1000;i++) { v[i].clear(); bcc[i].clear(); ma[i].clear(); } while(!s.empty())s.pop(); } int main() { int a,b,n=0,cnt=0; while(~scanf("%d",&a)) { if(a==0)break; init(); scanf("%d",&b); n=max(n,max(a,b)); v[a].pb(b); v[b].pb(a); ma[a][b]=ma[b][a]=1; while(~scanf("%d",&a)) { if(a==0)break; scanf("%d",&b); n=max(n,max(a,b)); if(!ma[a][b]) { v[a].pb(b); v[b].pb(a); ma[a][b]=ma[b][a]=1; } } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,-1); /* cout<<num<<endl; for(int i=1;i<=num;i++) { for(int j=0;j<bcc[i].size();j++) cout<<bcc[i][j]<<" "; cout<<endl; }*/ printf("Network #%d\n",++cnt); bool ok=0; for(int i=1;i<=n;i++) { if(iscut[i]>1) { ok=1; printf(" SPF node %d leaves %d subnets\n",i,iscut[i]); } } if(!ok)printf(" No SPF nodes\n"); puts(""); } return 0; } /************ ************/
以上是关于poj1523割顶-点双联通的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)