题意: 求有多少个割项,且每个割项被几个块所共有。
代码:
#include<iostream>
#include<string.h>
#include<vector>
#define mm 1010
using namespace std;
vector <int> vec[mm];
int stack[mm] , low[mm] , dfn[mm] ,gd[mm];
int top , step ,n , m ,xx;
void init()
{
for(int i=0;i<mm ; i++)
{
stack[i]=low[i]=dfn[i]=gd[i]=0;
vec[i].clear();
}
top=-1; step=n=m=0; xx=mm*999;
}
void insert(int u , int v)
{
vec[u].push_back(v);
vec[v].push_back(u);
dfn[u]=0; dfn[v]=0;
}
void tarjan(int u)
{
int v;
low[u]=dfn[u]=++step;
stack[++top]=u;
for(int i=0;i<vec[u].size(); i++)
{
v=vec[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[v] , low[u]);
if(low[v]>=dfn[u])
{// cout<<"u= "<<u<<endl;
if(dfn[u]!=xx && gd[u]==0 ) gd[u]+=2; //若u不是dfn[]最小的点,则若它为几个块的割点
else gd[u]++; //则u一定是被>=2个块所共有。
int temp;
do
{
temp=stack[top--];// cout<<u<<"----"<<temp<<endl;
}while(temp!=v);
}
}
else
low[u]=min(dfn[v] , low[u]);
}
}
int main()
{
int a, b;
int t=0;
while(scanf("%d",&a)!=EOF && a)
{
scanf("%d",&b);
init();
n=max(n, max(b , a)); xx=min(xx,min(a , b));
insert(a , b);
while(scanf("%d",&a) && a)
{
scanf("%d",&b);
n=max(n, max(a , b)); xx=min(xx,min(a , b));
insert(a , b);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i); //cout<<"m= "<<m<<endl;
printf("Network #%d\n",++t);
for(int i=1;i<=n;i++)
{//cout<<"**********"<<endl;
if(gd[i]!=0 && dfn[i]!=xx || gd[i]>1 && dfn[i]==xx) //要保证dfn[]最小的点是在图中的
{
m++;
printf(" SPF node %d leaves %d subnets\n",i,gd[i]);
}
}
if(m==0) printf(" No SPF nodes\n");
printf("\n");
}
return 0;
}