Linux安全网 - Linux操作系统_Linux 命令_Linux教程_Linux黑客

会员投稿 投稿指南 本期推荐:
搜索:
您的位置: Linux安全网 > Linux编程 > » 正文

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;
}

Tags:
分享至:
最新图文资讯
1 2 3 4 5 6
验证码:点击我更换图片 理智评论文明上网,拒绝恶意谩骂 用户名:
关于我们 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 发展历史