zoj1119SPF

割点算法
example
1 2
1 3
1 4
2 5
2 6
3 7
3 8
4 9
4 8
0
下面是算法运行过程 
from 1 enter to the adj ares 2
from 2 enter to the adj ares 5
end 5
return 2 is a cut node ,find subnet 1
from 2 enter to the adj ares 6
end 6
return 2 is a cut node ,find subnet 2
end 2
from 1 enter to the adj ares 3
from 3 enter to the adj ares 7
end 7
return 3 is a cut node ,find subnet 1
from 3 enter to the adj ares 8
from 8 enter to the adj ares 4
from 4 enter to the adj ares 9
end 9
return 4 is a cut node ,find subnet 1
end 4
end 8
end 3
return 1 is a cut node ,find subnet 1
end 1
运行结果:
Network #1
  SPF node 1 leaves 2 subnets
  SPF node 2 leaves 3 subnets
  SPF node 3 leaves 2 subnets
  SPF node 4 leaves 2 subnets

最后subnet数目要加一,因为cut[k]是孤立subnet,还要加上大后方

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int cut[1001],c[1001],ancestor[1001],d[1001],part[1001];
vector <int> adj[1001];
int ans;
int MAX,n,m;
void input(int n)
{
	if(n==0)return;
      scanf("%d",&m);
		adj[n].push_back(m);
		adj[m].push_back(n);
		MAX=max(MAX,max(m,n));	
		
}
void DFS(int k,int fa,int deep)
{
	int tot;
             c[k]=-1;
	d[k]=deep;
	ancestor[k]=deep,tot=0;
	for(int i=0;i<adj[k].size();i++)
	{
		int w=adj[k][i];
		if(w!=fa&&c[w]==-1)ancestor[k]=min( ancestor[k], d[w] );
		else if(c[w]==0)
		{
            //cout<<"from "<<k<<" enter to the adj ares "<<w<<endl;
			DFS(w,k,deep+1);
			tot++,ancestor[k]=min(ancestor[k],ancestor[w]);
			if(fa==-1&&tot>1||fa!=-1&&ancestor[w]>=d[k])
			{
				cut[k]++;//用来标记是否为割点及能分成几块连通区域(+1)
				//cout<<"return "<<k<<" is a cut node ,find subnet "<<cut[k]<<endl;
			}
		}	
	}
	c[k]=1;
	//cout<<"end "<<k<<endl;
}

int main()
{
	int cas=0;
	while(scanf("%d",&n)==1)
	{
		if(n==0)break;
		
	    for(int i=1;i<1001;i++)
		   adj[i].clear();

		MAX=-1;;
		
		input(n);
		while(scanf("%d",&n))
		{
			if(n==0)break;
			input(n);
		}
		memset(d,0,sizeof(d));
	    memset(c,0,sizeof(c));
	    memset(cut,0,sizeof(cut));
	    memset(ancestor,0,sizeof(ancestor));

		  DFS(1,-1,0);
		if(cas++)printf("\n");
		int ex=0;
        printf("Network #%d\n",cas);
        	for(int i=1;i<=MAX;i++)
			{
				if(cut[i]){printf("  SPF node %d leaves %d subnets\n",i,cut[i]+1);ex=1;}
			}
			if(!ex)printf("  No SPF nodes\n");
		
	}
}
posted on 2011-04-15 17:02  4.5.6  阅读(175)  评论(0编辑  收藏  举报