Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 31842 | Accepted: 11506 |
Description
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
Output
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!
Source
題意:
問是否存在次小生成樹,如果存在輸出'Not Unique!'. 否則輸出最小生成樹的權值和
思路:
用prime算法,每找到一條路就從重新開始判斷走過的路中是否存在多條可以到此點(代碼中p點)的路,並且距離相等,存在說明有次小生成樹,否則沒有。
代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int n,m;
int dis[105][105],dist[105];
int vis[105];
void prime(){
int sum=0;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
dist[i]=dis[1][i];
}
vis[1]=1;
m=n-1;
while(m--){
int minx=INF;
int p=0;
for(int i=1;i<=n;i++){
if(!vis[i] && dist[i]<minx){
minx=dist[i];
p=i;
}
}
if(p==0)break;
int k=0;
for(int i=1;i<=n;i++){//重新查找走過的路中是否還有此距離的最短路
if(vis[i] && dis[i][p]==minx){
k++;//每找到一條總數加一
}
}
if(k>1){//當超過一條時表示存在多條路
printf("Not Unique!\n");
return ;
}
vis[p]=1;
sum+=minx;
for(int i=1;i<=n;i++){
if(!vis[i] && dist[i]>dis[i][p])
dist[i]=dis[i][p];
}
}
printf("%d\n",sum);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int a,b,c;
memset(dis,INF,sizeof(dis));
for(int i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
dis[a][b]=dis[b][a]=min(dis[a][b],c);
}
prime();
}
return 0;
}