这是一道求割点的入门题,没什么好讲的,给一组详细的样例数据以供参考:
输入:
1 2
5 4
3 1
3 2
3 4
3 5
0
1 2
2 3
3 4
4 5
5 1
0
1 2
2 3
3 4
4 6
6 3
2 5
5 1
0
1 2
0
1000 999
999 998
998 997
997 1000
0
1 2
2 3
0
1 2
1 3
1 4
1 5
0
1 2
1 3
1 4
2 3
2 5
2 6
3 7
3 8
7 8
0
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
0
0
输出:
SPF node 3 leaves 2 subnets
Network #2
No SPF nodes
Network #3
SPF node 2 leaves 2 subnets
SPF node 3 leaves 2 subnets
Network #4
No SPF nodes
Network #5
No SPF nodes
Network #6
SPF node 2 leaves 2 subnets
Network #7
SPF node 1 leaves 4 subnets
Network #8
SPF node 1 leaves 2 subnets
SPF node 2 leaves 3 subnets
SPF node 3 leaves 2 subnets
Network #9
No SPF nodes
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
#include <vector>
#define AddEdge(x,y) a.push_back(edge(x,y))
#define MakeSmall(x,y) if(x>y) x=y
#define MaxN 1010
using namespace std;
int head[MaxN],tot;
int low[MaxN],dfn[MaxN],time;
int SubNet[MaxN];
int MinP;
bool CutP[MaxN],v[MaxN];
stack<int> st;
struct edge
{
int v,next;
edge(int x,int y):v(y),next(head[x])
{
head[x]=tot++;
}
};
vector<edge> a;
inline void InitGraph()
{
memset(head,-1,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(CutP,0,sizeof(CutP));
memset(v,0,sizeof(v));
memset(SubNet,0,sizeof(SubNet));
while(!st.empty()) st.pop();
time=tot=0,MinP=MaxN;
a.clear();
}
inline bool init()
{
InitGraph();
int x,y;
scanf("%d",&x);
if(!x) return 0;
scanf("%d",&y);
AddEdge(x,y),AddEdge(y,x);
MakeSmall(MinP,x);
MakeSmall(MinP,y);
for(;;)
{
cin>>x;
if(!x) return 1;
scanf("%d",&y);
AddEdge(x,y);
AddEdge(y,x);
MakeSmall(MinP,x);
MakeSmall(MinP,y);
}
}
void tarjan(int x,int p)
{
dfn[x]=low[x]=++time;
int ChNum=0,y;
st.push(x);
v[x]=1;
for(int i=head[x];~i;i=a[i].next)
{
y=a[i].v;
if(p==y) continue;
if(!dfn[y])
{
ChNum++;
tarjan(y,x);
low[x]=min(low[x],low[y]);
if(x!=p&&low[y]>=dfn[x])
{
CutP[x]=1;
SubNet[x]++;
}
}
else if(v[y])
low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x])
{
do
{
y=st.top();
st.pop();
v[x]=0;
}
while(x!=y);
}
if(x==p&&ChNum>1)
{
CutP[x]=1;
SubNet[x]=ChNum-1;
}
}
inline void work(int cas)
{
printf("Network #%d\n",cas);
tarjan(MinP,MinP);
bool flag=0;
for(int i=MinP;i<1001;i++)
if(CutP[i])
flag=1,
printf(" SPF node %d leaves %d subnets\n",i,SubNet[i]+1);
if(!flag) printf(" No SPF nodes\n");
}
int main()
{
int CASE=0;
while(init())
{
work(++CASE);
printf("\n");
}
return 0;
}