1393:联络员(liaison)

简介: 1393:联络员(liaison)

1393:联络员(liaison)

时间限制: 1000 ms         内存限制: 65536 KB

【题目描述】

Tyvj已经一岁了,网站也由最初的几个用户增加到了上万个用户,随着Tyvj网站的逐步壮大,管理员的数目也越来越多,现在你身为Tyvj管理层的联络员,希望你找到一些通信渠道,使得管理员两两都可以联络(直接或者是间接都可以)。Tyvj是一个公益性的网站,没有过多的利润,所以你要尽可能的使费用少才可以。

目前你已经知道,Tyvj的通信渠道分为两大类,一类是必选通信渠道,无论价格多少,你都需要把所有的都选择上;还有一类是选择性的通信渠道,你可以从中挑选一些作为最终管理员联络的通信渠道。数据保证给出的通行渠道可以让所有的管理员联通。

【输入】

第一行n,m表示Tyvj一共有n个管理员,有m个通信渠道;

第二行到m+1行,每行四个非负整数,p,u,v,w 当p=1时,表示这个通信渠道为必选通信渠道;当p=2时,表示这个通信渠道为选择性通信渠道;u,v,w表示本条信息描述的是u,v管理员之间的通信渠道,u可以收到v的信息,v也可以收到u的信息,w表示费用。

【输出】

最小的通信费用。

【输入样例】

5 6

1 1 2 1

1 2 3 1

1 3 4 1

1 4 1 1

2 2 5 10

2 2 5 5

【输出样例】

9

【提示】

【样例解释】

1-2-3-4-1存在四个必选渠道,形成一个环,互相可以到达。需要让所有管理员联通,需要联通2号和5号管理员,选择费用为5的渠道,所以总的费用为9。

【注意】

U,v之间可能存在多条通信渠道,你的程序应该累加所有u,v之间的必选通行渠道

【数据范围】

对于30%的数据,n≤10,m≤100;

对于50%的数据, n≤200,m≤1000

对于100%的数据,n≤2000,m≤10000

1. #include <iostream>
2. #include <stdio.h>
3. #include <algorithm>
4. using namespace std;
5. const int maxn=2010;  // 最大点数
6. const int maxm=20010; // 最大边数
7. struct point{
8. int x,y,c;  // 无向边(x,y),权值为c
9. }a[maxm];       // 存储询问的边
10. bool cmp(const point &a,const point &b){
11. return a.c<b.c;
12. }
13. int n,m,ans,k;    // n为点数,m为边数(包括询问边),ans为最小生成树的边权和,k为询问边的数量。
14. int f[maxn];      // 并查集,用于判断两个节点是否在同一集合
15. int find(int x){   // 查找x所属集合的代表元
16. if(f[x]==x) return x;
17. return f[x]=find(f[x]);  // 路径压缩
18. }
19. void unionn(int x,int y){  // 将x和y所属集合合并
20. int a=find(x);
21. int b=find(y);
22. if(a!=b) f[a]=b;
23. }
24. int main(){
25. scanf("%d %d",&n,&m);
26. for(int i=1;i<=n;i++) f[i]=i;  // 并查集初始化,每个节点的父亲为自己
27. int p,u,v,w;
28. for(int i=1;i<=m;i++){
29. scanf("%d %d %d %d",&p,&u,&v,&w);
30. if(p==1){  // 如果该边是连通操作,则将u和v所在的集合合并
31. unionn(u,v);ans+=w;
32.         }
33. else{     // 否则,将该边保存到a数组中,用于后续的Kruskal算法构造最小生成树
34.             k++;a[k].x=u;a[k].y=v;a[k].c=w;
35.         }
36.     }
37. sort(a+1,a+k+1,cmp);  // 对询问边按照权重进行排序
38. for(int i=1;i<=k;i++){
39. if(find(a[i].x)!=find(a[i].y)){  // 如果a[i]的两个端点不在同一个集合中,则可以选择使用这条边,将它们合并,并增加对应的权值。
40. unionn(a[i].x,a[i].y);
41.             ans+=a[i].c;
42.         }
43.     }
44. printf("%d",ans);  // 输出最小生成树的权值和
45. return 0;
46. }


相关文章
|
10月前
|
机器学习/深度学习 算法 C++
2019第十届蓝桥杯大赛青少年创意编程省赛C++组试题解析
2019第十届蓝桥杯大赛青少年创意编程省赛C++组试题解析
251 0
|
10月前
|
算法 C++ 容器
C/C++趣味程序设计百例(71~80)
C/C++趣味程序设计百例(71~80)
377 0
|
3月前
|
存储 设计模式 缓存
Java 中的 static:静态变量、静态方法,一切都在掌握中
Java 中的 static:静态变量、静态方法,一切都在掌握中
486 0
|
10月前
1395:烦人的幻灯片(slides)
1395:烦人的幻灯片(slides)
|
10月前
1394:连接格点(grid)
1394:连接格点(grid)
|
10月前
1299:糖果
1299:糖果
|
10月前
|
机器学习/深度学习
1277:【例9.21】方格取数
1277:【例9.21】方格取数
|
10月前
|
人工智能 BI C语言
1346:【例4-7】亲戚(relation)
1346:【例4-7】亲戚(relation)
|
10月前
10点小游戏 2021-04-22
10点小游戏 2021-04-22
|
10月前
|
算法 C++ 容器
C++学习笔记_14 迭代器、与容器无关的算法函数 2021-05-12
C++学习笔记_14 迭代器、与容器无关的算法函数 2021-05-12