The Unique MST(最小生成樹的唯一路徑)

最小生成樹唯一的路徑就是當前權值裏,僅有一條路可以走,不存在最小權值一樣的情況,如:1 2 2, 2 3 2, 1 3 2,第一次路徑爲1—2權值爲2,但當下一次到3這個點時就存在分歧,因爲1—3的權值是2,2—3的權值也是2,有兩個選擇。

例題: https://vjudge.net/contest/319242#problem/K

Given a connected undirected graph, tell if its minimum spanning tree is unique.
Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a
subgraph of G, say T = (V’, E’), with the following properties:
1. V’ = V.
2. T is connected and acyclic.
Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E).
The minimum spanning tree T = (V, E’) of G is the spanning tree that has the smallest total cost. The total cost of
T means the sum of the weights on all the edges in E’.
Input
The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.
Output
For each input, if the MST is unique, print the total cost of it, or otherwise print the string ‘Not Unique!’.
Sample Input

2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2

Sample Output

3
Not Unique!

解題思路:最短路徑的prime算法,求出每一次到頂點的權值,然後比較各個點到最短邊的權值是否有相同的,注意:會存在至少一條邊滿足相同,那就是本身這條邊。

程序代碼:

#include<stdio.h>
#include<string.h>
int e[2000][2000],dis[5000],book[5000];
int inf=99999999;
int main()
{
	int i,j,k,n,m,t1,t2,t3,min,l,v,sun;
	int count,sum;
	int N,flag;
	scanf("%d",&N);
	while(N--)
	{
		flag=0;
		count=0;
		sum=sun=0;
		l=1;
		memset(dis,0,sizeof(dis));
		memset(book,0,sizeof(book));
		memset(f,0,sizeof(f));
		memset(a,0,sizeof(a));
		scanf("%d%d",&n,&m);
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				if(j==i)	e[i][j]=0;
				else		e[i][j]=inf;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&t1,&t2,&t3);
			if(e[t1][t2]>t3)//可能同樣的邊會出現兩次,所以取較短的邊
			{
				e[t1][t2]=t3;
				e[t2][t1]=t3;
			}
		}
		for(i=1;i<=n;i++)
			dis[i]=e[1][i];
		book[1]=1;
		count++;
		while(count<n)
		{
			min=inf;
			for(i=1;i<=n;i++)
			{
				if(book[i]==0&&dis[i]<min)
				{
					min=dis[i];
					j=i;
				}
			}
			sun=0;//初始化有相同邊的數目
			for(v=1;v<=n;v++)//尋找n條邊中已經標記的的邊中是否有相同的邊
				if(book[v]==1&&min==e[v][j])
					sun++;
			if(sun>1)//sun>1說明最少有一條邊與當前最小值一樣
				break;
			book[j]=1;
			sum+=dis[j];
			count++;
			for(k=1;k<=n;k++)
				if(book[k]==0&&dis[k]>e[j][k])
					dis[k]=e[j][k];	
		}
		if(sun<=1)
			printf("%d\n",sum);
		else
			printf("Not Unique!\n");
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章