ACM程序设计选修课——Problem E:(ds:图)公路村村通(优先队列或sort+克鲁斯卡尔+并查集优化)
畅通工程
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24323 Accepted Submission(s): 10621
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
?
先引用百度百科
先构造一个只含 n 个顶点、而边集为空的子图,把子图中各个顶点看成各棵树上的根结点,之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,即把两棵树合成一棵树,反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直到森林中只有一棵树,也即子图中含有
n-1 条边为止。
最后一句很重要,停止条件是子图中含有n-1条边为止。
还有就是选取每一条边的时候要看看是否能与之前已选中的构成回路,不构成回路则选择一条距离最短的,若能构成回路则舍弃。
嗯这题无聊玩了一下操作符重载(刚开始写反了输出的结果比较大。),比较有意思的。鉴于sort的复杂度不大两者应该没啥差别,就是不用vector的情况下空间可以节省一点……没错我就是这么无聊= =
sort写法:
- #include<iostream>
- #include<algorithm>
- #include<cstdlib>
- #include<sstream>
- #include<cstring>
- #include<cstdio>
- #include<string>
- #include<deque>
- #include<stack>
- #include<cmath>
- #include<queue>
- #include<set>
- #include<map>
- #define INF 0x3f3f3f3f
- #define MM(x) memset(x,0,sizeof(x))
- using namespace std;
- typedef long long LL;
- const int N=1010;
- struct info
- {
- int a;
- int b;
- int val;
- info(){a=b=val=0;}
- };
- info G[3*N];
- int vis[N];
- void init()
- {
- MM(G);
- for (int i=0; i<N; i++)
- vis[i]=i;
- }
- bool cmp(const info &a,const info &b)
- {
- return a.val<b.val;
- }
- inline int find(int a)
- {
- if(vis[a]!=a)
- return vis[a]=find(vis[a]);
- return vis[a];
- }
- inline int merge(const int &a,const int &b)
- {
- int aa=find(a),bb=find(b);
- if(aa!=bb)
- {
- vis[bb]=aa;
- return 1;
- }
- return 0;
- }
- int main(void)
- {
- int tcase,i,x,y,val,n,m;
- scanf("%d",&tcase);
- while (tcase--)
- {
- scanf("%d%d",&n,&m);
- init();
- int ans=0,cnt=0;
- for (i=1; i<=m; i++)
- {
- scanf("%d%d%d",&G[i].a,&G[i].b,&G[i].val);
- }
- sort(G+1,G+m+1,cmp);
- for (i=1; i<=m; i++)
- {
- if(cnt==n-1)
- break;
- if(merge(G[i].a,G[i].b))
- {
- cnt++;
- ans+=G[i].val;
- }
- }
- cnt==n-1?printf("%d\n",ans):puts("-1");
- }
- return 0;
- }
优先队列写法:
- #include<iostream>
- #include<algorithm>
- #include<cstdlib>
- #include<sstream>
- #include<cstring>
- #include<cstdio>
- #include<string>
- #include<deque>
- #include<stack>
- #include<cmath>
- #include<queue>
- #include<set>
- #include<map>
- #define INF 0x3f3f3f3f
- #define MM(x) memset(x,0,sizeof(x))
- using namespace std;
- typedef long long LL;
- const int N=1010;
- struct info
- {
- int a;
- int b;
- int val;
- bool operator<(const info &b) const
- {
- return val>b.val;
- }
- };
- info G;
- int vis[N];
- priority_queue<info> Q;
- void debug(priority_queue<info> q)
- {
- while (!q.empty())
- {
- cout<<q.top().a<<" "<<q.top().b<<endl;
- q.pop();
- }
- }
- void init()
- {
- for (int i=0; i<N; i++)
- {
- vis[i]=i;
- }
- while (!Q.empty())
- Q.pop();
- }
- inline int find(int a)
- {
- if(vis[a]!=a)
- return vis[a]=find(vis[a]);
- return vis[a];
- }
- inline bool merge(int a,int b)
- {
- int aa=find(a),bb=find(b);
- if(aa!=bb)
- {
- vis[bb]=aa;
- return true;
- }
- return false;
- }
- int main(void)
- {
- int tcase,i,j,x,y,val,n,m;
- scanf("%d",&tcase);
- while (tcase--)
- {
- scanf("%d%d",&n,&m);
- init();
- int ans=0,cnt=0;
- for (i=0; i<m; i++)
- {
- scanf("%d%d%d",&G.a,&G.b,&G.val);
- Q.push(G);
- }
- //debug(Q);
- while (!Q.empty())
- {
- info t=Q.top();
- Q.pop();
- if(cnt==n-1)
- break;
- if(merge(t.a,t.b))
- {
- cnt++;
- ans+=t.val;
- }
- }
- cnt==n-1?printf("%d\n",ans):puts("-1");
- }
- return 0;
- }
ACM程序设计选修课——Problem E:(ds:图)公路村村通(优先队列或sort+克鲁斯卡尔+并查集优化)的更多相关文章
- ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)
问题 E: (ds:图)公路村村通 时间限制: 1 Sec 内存限制: 128 MB 提交: 9 解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...
- ACM程序设计选修课——Problem F:(ds:图)旅游规划(优先队列+SPFA)
问题 F: (ds:图)旅游规划 时间限制: 1 Sec 内存限制: 128 MB 提交: 14 解决: 4 题目描述 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路 ...
- ACM程序设计选修课——Problem D: (ds:树)合并果子(最优二叉树赫夫曼算法)
Problem D: (ds:树)合并果子 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 80 Solved: 4 [Submit][Status][ ...
- pta08-图7 公路村村通 (30分)
08-图7 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...
- pat06-图6. 公路村村通(30)
06-图6. 公路村村通(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的 ...
- 7-6 公路村村通(30 分) 【prime】
7-6 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤10 ...
- 7-10 公路村村通(30 分)(最小生成树Prim算法)
7-10 公路村村通(30 分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1 ...
- PTA 7-1 公路村村通 (30分)
PTA 7-1 公路村村通 (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N ...
- PTA 08-图7 公路村村通 (30分)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道 ...
随机推荐
- 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02) A Amusing Numbers (数学)
其实挺简单的.先直接算出之前已经排在k这个数前面的数字.比如543是三位的,那么100~543都是可以的,两位的10~54. 如果还需要往前面补的话,那么依次考虑1000~5430,5430是上界不能 ...
- python 与 json
+-------------------+---------------+ | Python | JSON | +================= ...
- /^/m|/$/m|\b|\B|$&|$`|$'|变量捕获|()?|(?:pattern)|(?<LABEL>PATTERN)|$+{LABEL}|(|)|\g{LABEL}
#!/usr/bin/perl use strict; use warnings; $_=' $$ oinn &&& ninq kdownc aninp kkkk'; if ( ...
- OI算法复习
搜集一些算法,赛前背一背有好处的 转自各大网站 前排感谢:hzwer.风了咕凉 前辈...Orz 快速读入: int read() { ,f=;char ch=getchar(); ;ch=getch ...
- 【wqs二分】HHHOJ#15. 赤
这个wqs二分并不熟练…… 题目描述 #15. 赤 题目分析 两维都用wqs二分,其他没有什么特殊之处. 重点在于,wqs二分还原最优解的时候,增量是强制给的k. #include<bits/s ...
- 01windows常用命令及批处理
1. 概述 复制内容:右键弹出快捷菜单,选择"标记(K)",然后选中所需要的内容,然后右键即可 粘贴内容:右键弹出快捷菜单,选择"粘贴(P)" 命令参数的路径: ...
- DNS预解析 dns-prefetch
1.DNS 是什么? Domain Name System,域名系统,作为域名和IP地址相互映射的一个分布式数据库. DNS大家都懂,那么浏览器访问域名的时候,是需要去解析一次DNS,也就是把域名 g ...
- 【mac】【转发】Mac系统升级后,按大小写键没反应了,切换大小写的灯不亮了
Mac系统升级后发现caps lock 锁定大小写的键,失灵了,居然可以用来切换输入法了,经过一排查后, 使用以下几种方法处理: 方式一:长按 caps lock 键,来切换大小写 方式二:caps ...
- Python 建模步骤
#%% #载入数据 .查看相关信息 import pandas as pd import numpy as np from sklearn.preprocessing import LabelEnco ...
- Python学习笔记:字符串
字符串 字符串定义:字符串可以使用一对单引号.双引号或三引号来定义,即便是单个字符也会当做字符串来处理(Python中没有字符类型,单个字符也就是只有一个字符的字符串而已). 原始字符串:字符串中反斜 ...