PKU1679判断最小生成树是否唯一Prime算法

来源:互联网 发布:网络组策略开启端口 编辑:程序博客网 时间:2024/06/04 23:42
原题http://poj.org/problem?id=1679
//本题是判断最小生成树是否唯一,可以根据先删除最小生成树里面的边然后新加入一条边,然后判断新生成的最小生成树的权值和原来是否相同//这就要求要求原来最小生成树里任意两个点之间的最大值。#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <limits.h>#include <ctype.h>#include <string.h>#include <string>#include <algorithm>#include <iostream>//#include <stack>#include <queue>#include <deque>#include <set>#include <vector>#include <math.h>#include <set>using namespace std;#define INF 999999999#define N 111int n,m;int pre[N],dis[N][N],max1[N][N],g[N];int vis[N],stack[N];int sum;int max(int a,int b){if(a > b)return a;elsereturn b;}int minn(int a,int b){if(a < b)return a;elsereturn b;}void Prime(){int i,j,k;memset(vis,0,sizeof(vis));memset(g,0,sizeof(g));for(i=1;i<=n;i++){g[i] = dis[1][i];pre[i] = 1;}vis[1] = 0;int top=0;sum = 0;stack[top++] = 1;int tmp;for(i=1;i<=n;i++){tmp = INF;for(j=1;j<=n;j++){if(tmp>g[j] && vis[j]==0){tmp = g[j];k = j;}}vis[k] = 1;if(tmp == INF)break;sum+=tmp;for(j=0;j<top;j++){max1[stack[j]][k] = max(max1[stack[j]][pre[k]],tmp);//x新加入的点到最小生成树里面每个点的最大距离,前面的代表与这个点相连的那个,后面的代表选择出来的值}max1[k][stack[j]] = max1[stack[j]][k];}stack[top++] = k;for(j=1;j<=n;j++){if(vis[j]==0 && dis[k][j]<g[j]){g[j] = dis[k][j];pre[j] = k;}}}}int main(){int T;int i,j;int a,b,c;while(~scanf("%d",&T)){while(T--){scanf("%d%d",&n,&m);for(i=0;i<N;i++){for(j=0;j<N;j++){dis[i][j] = INF;max1[i][j] = 0;}}for(i=0;i<N;i++){dis[i][i] = 0;}for(i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);dis[a][b] = c;dis[b][a] = c;}Prime();int min = INF;for(i=1;i<=n;i++){//遍历原最小生成树里面以外的任意边。for(j=1;j<=n;j++){if(i!=j && i!=pre[j] && j!=pre[i]){min = minn(min,dis[i][j]-max1[i][j]);}}}if(min != 0){printf("%d\n",sum);}else{printf("Not Unique!\n");}}}return 0;}

0 0
原创粉丝点击