1. 程式人生 > >poj1523割頂-點雙聯通

poj1523割頂-點雙聯通

lap net out truct onclick fine while cnblogs else

題意:求出所有的割頂,而且還有輸出該割頂連接了幾個點雙連通分量

題解:直接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; } /************ ************/
View Code

poj1523割頂-點雙聯通