標籤:put span map 注意 none event mem tar break
題意:求出所有的割頂,而且還有輸出該割頂串連了幾個點雙連通分量
題解:直接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|1using 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割頂-點雙聯通