最小生成树
来源:互联网 发布:网络机顶盒能接音响吗 编辑:程序博客网 时间:2024/06/04 23:31
最小生成树
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 113 Accepted Submission(s): 11
Problem Description
ap最近学习了最小生成树树之后,向你提了这么一个问题:给一个n个节点的完全图,节点编号从1-n, 如果限制这个完全图的生成树中k个点的度数为1,那么还能否构造出最小生成树呢?
Input
第一行一个正整数T,代表有T组数据
每组数据,第一个两个正整数n, k (2 <= n <= 300, 0 <= k <= n)
接下来n*(n-1)/2行,每行三个正整数ui, vi, wi, 代表节点ui和节点vi之间有一条权值为wi的边 (0 <= wi <= 10000)
最后一行, k个互不相同的数fi, 代表限制度数为1的节点的编号
输入保证给出的是完全图
每组数据,第一个两个正整数n, k (2 <= n <= 300, 0 <= k <= n)
接下来n*(n-1)/2行,每行三个正整数ui, vi, wi, 代表节点ui和节点vi之间有一条权值为wi的边 (0 <= wi <= 10000)
最后一行, k个互不相同的数fi, 代表限制度数为1的节点的编号
输入保证给出的是完全图
Output
每组数据,若符合条件的最小生成树存在,输出该最小生成树所有边权之和; 若不存在, 输出-1
Sample Input
33 01 2 12 3 23 1 33 11 2 12 3 23 1 323 31 2 12 3 23 1 31 2 3
Sample Output
34-1
解题思路:若度为一的点是所有点,当n等于2的时候,答案就是唯一边权,否则就是形不成最小生成树,若度为一的点小于顶点数,那么先将度不为一的点用最小边连起来,再找和度为一的点最近的边(边的连点都为度为一的点是不能取的)
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <set>#include <bitset>#include <stack>#include <map>#include <climits>#include <functional>using namespace std;#define LL long longconst int INF=0x3f3f3f3f;struct node{ int s,e,w,flag;}x[90000];int k,a[350];int f[350],n;int sum[350];int Find(int x){ if(f[x]==x) return x; return f[x]=Find(f[x]);}bool cmp(node a,node b){ return a.w<b.w;}int main(){ int t; scanf("%d",&t); while(t--) { int p; memset(a,0,sizeof a); scanf("%d %d",&n,&k); for(int i=1;i<=(n-1)*n/2;i++) scanf("%d %d %d",&x[i].s,&x[i].e,&x[i].w),x[i].flag=0; for(int i=1;i<=k;i++) scanf("%d",&p),a[p]=1; if(n==k) { if(n==2) {printf("%d\n",x[1].w);continue;} else printf("-1\n"); } for(int i=1;i<=n;i++) f[i]=i; memset(sum,0,sizeof sum); sort(x+1,x+1+n*(n-1)/2,cmp); int cnt=0,ans=0; for(int i=1;i<=(n-1)*n/2;i++) { if(a[x[i].s]) continue; if(a[x[i].e]) continue; int ss=Find(x[i].s),ee=Find(x[i].e); if(ss!=ee) { f[ss]=ee; cnt++; ans+=x[i].w; x[i].flag=1; } if(cnt==n-1) break; } for(int i=1;i<=(n-1)*n/2;i++) { if(cnt==n-1) break; if(x[i].flag) continue; if(a[x[i].s]&&a[x[i].e]) continue; if(a[x[i].s]&&sum[x[i].s]) continue; if(a[x[i].e]&&sum[x[i].e]) continue; int ss=Find(x[i].s),ee=Find(x[i].e); if(ss!=ee) { if(a[x[i].s]) sum[x[i].s]++; else if(a[x[i].e]) sum[x[i].e]++; f[ss]=ee; cnt++; ans+=x[i].w; } if(cnt==n-1) break; } printf("%d\n",ans); } return 0;}
0 0
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树Kruskal
- kruskal 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树问题
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- leetcode:72. Edit Distance
- hdu 置换群
- 1070. 结绳(25)
- selenium 超时设置/等待时间过长自动停止(python)
- iOS 两种压缩方式比较
- 最小生成树
- 数据结构实验之链表三:链表的逆置
- L1-009. N个数求和
- HashMap&&HshTable以及简单实现HashMap
- 调试休眠和唤醒
- CSS制作水平垂直居中对齐
- HBase原理-数据读取流程解析
- CAGradientLayer学习
- 《ACM程序设计》书中题目Y-25