poj 1679 Kruskal+MST环性质

题意:在一个无向图中,若其最小生成树唯一,则输出其值;若不唯一则输出“Not Unique!”。

《算法:C语言实现》这本书将MST有两个重要性质:割性质和环性质。本题则用到了MST的环性质。也就是说在一个无向连通图中可以将边分为MST上的边和非MST上的边,若将非MST上的边e加入MST中一定会形成一个环。所以先用Kruskal算法求出MST,然后以e的一个端点开始在MST上进行深搜,找到到达另一个端点路径,查看这条路径上边的权值是否有和e的权值相等的。若有则不是唯一的,若将每个e都测试一遍都没有和e的权值相等的则是唯一的。这样说够通俗易懂了吧……然而我看到网上很多人用次小生成树的解法来做,这种解法当然是正确的。但本题只是让判断唯一不唯一,本人认为没必要那样做,我的思路已经说过了,以下是我的代码:

#include<iostream>

#include<cstring>

#include<vector>

using namespace std;

struct node

{

	int start;

	int end;

	int value;

};

struct Adjvex

{

	int v;

	int value;

};

int root[101],wight[101],visit[101];

node ss[10001],tt[10001];

vector <Adjvex> map[101];

bool flag;

int cmp(const void* a,const void * b)

{

	return  ((node *)a)->value-((node*)b)->value;

}

int find(int i)

{

	while(root[i]!=i)

		i=root[i];

	return i;

}

int dfs(int s,int t,int w)//搜索环路径

{

	int j;

	visit[s]=1;

	if(s==t) return 1;

	for(j=0;j<map[s].size();j++)

		if(!visit[map[s][j].v] && dfs(map[s][j].v,t,w))

		{

			if(map[s][j].value==w) flag=true;

			return 1;

		}

	//visit[s]=0;

    return 0;

}

int Union(int s,int t)

{

    if(wight[s]>=wight[t])

	{

		root[t]=s;

		wight[s]+=wight[t];

	}

	else

	{

		root[s]=t;

		wight[t]+=wight[s];

	}

	return 0;

}

int add(node s)//构造MST的数据结构,搜索时用

{

    Adjvex e={s.end,s.value};

	map[s.start].push_back(e);

	e.v=s.start;

	map[s.end].push_back(e);

	return 0;

}

int main()

{

	int i,k,m,n,N,sum,s,t,count;

	cin>>n;

	while(n--)

	{

		cin>>m>>k;

		for(i=0;i<k;i++)

			cin>>ss[i].start>>ss[i].end>>ss[i].value;

        qsort(ss,k,sizeof(ss[0]),cmp);

        for(i=1;i<=m;i++)

		{ 

			root[i]=i; wight[i]=1;

		}

		sum=N=count=0;

		for(i=0;i<k;i++)

		{

			s=find(ss[i].start);

			t=find(ss[i].end);

			if(s==t)

			{ 

				tt[N++]=ss[i]; continue; 

			}

			Union(s,t);

			add(ss[i]);

			sum+=ss[i].value;

			//if(count++>=m-1) break;

		}

		for(flag=false,i=0;i<N;i++)

		{

			memset(visit,0,sizeof(visit));

			dfs(tt[i].start,tt[i].end,tt[i].value);

			if(flag) break;

		}

		if(flag)

			cout<<"Not Unique!"<<endl;

		else

			cout<<sum<<endl;

		for(i=0;i<=m;i++)

			map[i].clear();

	}

	return 0;

}

你可能感兴趣的:(poj)