路中權值最大的那條邊的權值. (注意這裏).
這是很容易做到的,因爲prim是每次增加一個結點s, 而設已經標號了的結點
集合爲W, 則W中所有的結點到s的路中的最大權值的邊就是當前加入的這條邊.
step 1 用時 O(V^2).
step 2. 枚舉所有不在T中的邊uv, 加入邊uv則必然替換權爲max[u][v]的邊。
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 29427 | Accepted: 10529 |
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!
code:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=510;
#define inf 0x3f3f3f3f
int n,E;
int vis[N],used[N][N],map[N][N],MAX[N][N],low[N],pre[N];
//used標記邊是否在最小生成樹中,MAX[i][j]存i-j在MST中的最大邊權
int prim()
{
memset(vis,0,sizeof(vis));
memset(used,0,sizeof(used));
memset(pre,0,sizeof(pre));
memset(MAX,0,sizeof(MAX));
memset(low,0,sizeof(low));
int p,minn,ans=0;
vis[1]=1;
p=1;
for(int i=1;i<=n;i++)
{
low[i]=map[p][i];
pre[i]=p;
}
for(int i=1;i<n;i++)
{
minn=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&minn>low[j])
{
minn=low[j];
p=j;
}
}
ans+=minn;
used[p][pre[p]]=used[pre[p]][p]=1;//標記,與MST的不同之處
vis[p]=1;
for(int j=1;j<=n;j++)
{
if(vis[j]) MAX[p][j]=MAX[j][p]=max(MAX[j][pre[p]],low[p]);//與MST的不同之處
if(!vis[j]&&low[j]>map[p][j])
{
low[j]=map[p][j];
pre[j]=p;//更新,與MST的不同之處
}
}
}
return ans;
}
int main()
{
int T,x,y,z;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&E);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) map[i][j]=0;
else
map[i][j]=inf;
}
}
while(E--)
{
scanf("%d%d%d",&x,&y,&z);
if(map[x][y]>z)
{
map[x][y]=z;
}
if(map[y][x]>z)
{
map[y][x]=z;
}
}
int result=prim();
int flag=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(!used[i][j])
{
if(map[i][j]==MAX[i][j])//尋找是否有不在MST中,但和MST中權值相同的邊
{
flag=1;break;
}
}
}
if(flag) break;
}
if(flag) printf("Not Unique!\n");
else
printf("%d\n",result);
}
}