poj1679

来源:互联网 发布:淘宝怎么买电话轰炸 编辑:程序博客网 时间:2024/05/16 19:06

题意大概是说判断最小生成树是否是唯一的,如果唯一的就输出最小权值,否则输出 No Unique!

网上的思路是:先求最小生成树,并且把边记录下来,然后将最小生成树的各个边删掉,判断是否还能生成一和个原来权值一样的树,如果可以就不唯一,否则唯一。
#include<iostream>#include<algorithm>#include<stdlib.h>#include<string.h>#include<string>#include<vector>#include<queue>#include<list>using namespace std;typedef long long lld;typedef unsigned int ud;#define Inf INT_MAX//int最大#define Min(x,y) (x)<(y)?(x):(y)#define Max(x,y) (x)>(y)?(x):(y)#define PQ priority_queue#define Q queue#define N 102#define M 10002struct Node{int u,v;int w;}edge[M];int parent[N];int n,m;int MST_edge[N];void InitParent(){for(int i=1;i<=n;i++)parent[i]=-1;}int find(int x){return parent[x]<0 ? x : find(parent[x]);}void merge(int r1,int r2){if(parent[r1]>parent[r2]){parent[r1]=r2;//parent[r2]+=parent[r1];}else{parent[r2]=r1;//parent[r1]+=parent[r2];}}bool cmp(Node n1,Node n2){return n1.w<n2.w;}void Kruskal(){sort(edge+1,edge+m+1,cmp);int res=0;InitParent();int k=1;for(int i=1;i<=m;i++){if(k>n-1)break;int u=find(edge[i].u);int v=find(edge[i].v);if(u!=v){res+=edge[i].w;merge(u,v);//加入生成树的边MST_edge[k++]=i;}}for(int i=1;i<=n-1;i++){int sumW=0;int mst_n=0;InitParent();for(int j=1;j<=m;j++){if(j==MST_edge[i])continue;int u=find(edge[j].u);int v=find(edge[j].v);if(u!=v){sumW+=edge[j].w;mst_n++;merge(u,v);}}if(mst_n!=n-1)continue;if(sumW==res){printf("Not Unique!\n");return ;}}printf("%d\n",res);}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){//int u,v,w;scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);}Kruskal();}return 0;}
0 0
原创粉丝点击