20211123 HDU练习 最短路和最小生成树
一些模板题,都是dijkstra和prim
第一次写博客就复制黏贴实验报告非常抱歉,下次一定好好写。()
以后自己做的题也会写点题解吧 欢迎找我玩~
HDU Today
Time Limit : 15000/5000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 40 Accepted Submission(s) : 2
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强。这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬浦镇陶姚村买了个房子,开始安度晚年了。
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
Input
输入数据有多组,每组的第一行是公交车的总数N(0<=N<=10000);
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
Output
如果徐总能到达目的地,输出最短的时间;否则,输出“-1”。
Sample Input
6
xiasha westlake
xiasha station 60
xiasha ShoppingCenterofHangZhou 30
station westlake 20
ShoppingCenterofHangZhou supermarket 10
xiasha supermarket 50
supermarket westlake 10
-1
Sample Output
题目的分析
最短路径问题,难点在每个节点的输入不是编号而是字符串形式的地名。
以及没给样例输出
解决方法:用一个map<string,int> ,以地名为键值编号就好啦。STL真好用!
用了优先队列优化的dijkstra
代码
#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fint n;int graph[155][155];string start,endd;int dis[105];bool vis[105];int main(){int t,cnt,i;string s,e;map<string,int> mapp;while(1){cin >> n;if(n==-1) break;cin >> start >> endd;mapp.clear();memset(graph,INF,sizeof(graph));cnt=1;mapp[start]=1;if(!mapp[endd]) mapp[endd]=++cnt;while(n--){cin >> s >> e >> t;if(!mapp[s]) mapp[s]=++cnt;if(!mapp[e]) mapp[e]=++cnt;//cout << s << " " << mapp[s] << endl;//cout << e << " " << mapp[e] << endl;graph[mapp[s]][mapp[e]]=graph[mapp[e]][mapp[s]]=t;}memset(vis,false,sizeof(vis));memset(dis,INF,sizeof(dis));vis[0]=true;dis[1]=0;priority_queue<pair<int,int>> q; //(-长度,结点编号)for(i=2;i<=n;i++){dis[i]=graph[1][i];if(dis[i]!=INF){q.push(make_pair(-dis[i],i));}}q.push(make_pair(-0,1));while(!vis[mapp[endd]]){i=0;while(vis[i]){i=q.top().second;q.pop(); }vis[i]=true;for(int j=1;j<=cnt;j++){if(!vis[j] && dis[j]>dis[i]+graph[i][j]){dis[j]=dis[i]+graph[i][j];q.push(make_pair(-dis[j],j));}}}if(dis[mapp[endd]]!=INF) cout << dis[mapp[endd]];else cout << "-1";cout << endl;}return 0;}
代码运行情况
美美过了
感想
在做最短路径/最小生成树问题的时候,需要有的一些习惯:
- 是否有重边?
- 是否有负值边/负值圈?(选择不同算法)
- 是否需要输出路径,还是只需要计算路径长度?
- 根据图是稀疏或稠密选择算法(暂时没遇到卡得很严格的题)
- 优化一下总是没错的,多用scanf少用cin总是没错的
畅通工程
Time Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 90 Accepted Submission(s) : 20
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
Sample Input
3 31 2 11 3 22 3 41 32 3 20 100
Sample Output
3?
Source
浙大计算机研究生复试上机考试-2007年
题目的分析
最小生成树问题。用prim算法,因为不确定N的大小,还是不用kruskal冒险了(其实是前一题写了dijkstra好改)
代码
#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fint main(){int n,m,i,j,k,visted,ans;int w[105][105];int dis[105];bool vis[105];while(1){cin >> n >> m;if(n==0) break;memset(w,INF,sizeof(w));while(n--){cin >> i >> j >> k;if(w[j][i]>k) w[i][j]=w[j][i]=k;}ans=visted=0;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));priority_queue<pair<int,int>> q;dis[1]=0; vis[0]=true;for(i=2;i<=m;i++){dis[i]=w[1][i];if(dis[i]!=INF){q.push(make_pair(-dis[i],i));}}q.push(make_pair(0,1));while(!q.empty()){i=0;while(vis[i] && (!q.empty())){i=q.top().second;q.pop();}if(i==0) break;vis[i]=true;visted++;ans+=dis[i];for(j=2;j<=m;j++){if((!vis[j]) && dis[j]>w[i][j]){dis[j]=w[i][j];q.push(make_pair(-dis[j],j));}}}if(visted==m) cout << ans << endl;else cout << "?" << endl;}return 0;}
代码运行情况
美美过了
感想
对Kruskal的应用场景产生怀疑,决定找点相关题目做做。
还是畅通工程
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 40 Accepted Submission(s) : 15
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
Sample Output
35
Hint
Hint
Huge input, scanf is recommended.
Source
浙大计算机研究生复试上机考试-2006年
题目的分析
还是最小生成树问题。这次说了是稠密图,可能意思是1002要写kruskal吧 TT。
用之前的代码改了一下,还好今天的题目都没有负权边。
注意循环的退出条件,在所有顶点都访问过(visted==m )的时候就可以退出了。
代码
#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fint main(){int n,m,i,j,k,visted,ans;int w[105][105];int dis[105];bool vis[105];while(1){cin >> m;n=m*(m-1)/2;if(m==0) break;memset(w,INF,sizeof(w));while(n--){//cin >> i >> j >> k;scanf("%d%d%d",&i,&j,&k);if(w[j][i]>k) w[i][j]=w[j][i]=k;}ans=visted=0;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));priority_queue<pair<int,int>> q;dis[1]=0; vis[0]=true;for(i=2;i<=m;i++){dis[i]=w[1][i];if(dis[i]!=INF){q.push(make_pair(-dis[i],i));}}q.push(make_pair(0,1));while(!q.empty()){i=0;while(vis[i] && (!q.empty())){i=q.top().second;q.pop();}if(i==0 || visted==m) break;vis[i]=true;visted++;ans+=dis[i];for(j=2;j<=m;j++){if((!vis[j]) && dis[j]>w[i][j]){dis[j]=w[i][j];q.push(make_pair(-dis[j],j));}}}/*cout << visted << endl;if(visted==m) cout << ans << endl;else cout << "?" << endl;*/cout << ans << endl;}return 0;}
代码运行情况
美美过了
感想
此处空白
最短路
Time Limit : 5000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 114 Accepted Submission(s) : 30
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 11 2 33 31 2 52 3 53 1 20 0
Sample Output
32
Source
UESTC 6th Programming Contest Online
题目的分析
最短路径,dijkstra。
代码
#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fint main(){int n,m,i,j,k,visted;int w[105][105];int dis[105];bool vis[105];while(1){//cin >> n >> m;cin >> m >> n;if(n==0 && m==0) break;memset(w,INF,sizeof(w));while(n--){cin >> i >> j >> k;if(w[j][i]>k) w[i][j]=w[j][i]=k;}visted=0;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));vis[1]=true;dis[1]=0;for(i=2;i<=m;i++){dis[i]=w[1][i];}for(i=2;i<=m;i++){int min,pos;min=INF;for(j=2;j<=m;j++){if((!vis[j]) && dis[j]<min){min=dis[j];pos=j;}}if(min==INF) break;vis[pos]=true;if(vis[m]) break;for(j=2;j<=m;j++){if((!vis[j]) && dis[j]>dis[pos]+w[pos][j]){dis[j]=dis[pos]+w[pos][j];}} }cout << dis[m] << endl;}return 0;}
代码运行情况
美美过了
感想
此处空白
最短路径问题
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 1
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output
输出 一行有两个数, 最短距离及其花费。
Sample Input
3 21 2 5 62 3 4 51 30 0
Sample Output
9 11
Source
浙大计算机研究生复试上机考试-2010年
题目的分析
最短路径,dijkstra!好像有同学写floyd,那是必定要超时的。
“长度d和花费p”其实就是主次关键字,在更新dis[]和寻找下一个访问的顶点时注意更新条件就可以了。
然后起点终点并不默认是1和n,复制黏贴的时候要注意
代码
#include<bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fint n,m,i,j,d,p,visted,s,t;int w[1005][1005];int mm[1005][1005];int dis[1005],cost[1005];bool vis[1005];int main(){while(1){//cin >> n >> m;cin >> m >> n;if(n==0 && m==0) break;memset(w,INF,sizeof(w));memset(mm,INF,sizeof(m));while(n--){//cin >> i >> j >> d >> p;scanf("%d%d%d%d",&i,&j,&d,&p);if((w[j][i]>d) || (w[j][i]==d && mm[j][i]>p)){w[i][j]=w[j][i]=d;mm[i][j]=mm[j][i]=p;}}scanf("%d%d",&s,&t);visted=0;memset(dis,INF,sizeof(dis));memset(vis,false,sizeof(vis));memset(cost,INF,sizeof(cost));for(i=1;i<=m;i++){dis[i]=w[s][i];cost[i]=mm[s][i];}vis[s]=true;dis[s]=0;cost[s]=0;for(i=1;i<=m;i++){int min,pos,mincost;mincost=min=INF;for(j=1;j<=m;j++){if((!vis[j]) && (dis[j]<min || (dis[j]==min && cost[j]<mincost))){min=dis[j];mincost=cost[j];pos=j;}}if(min==INF) break;vis[pos]=true;if(vis[t]) break;for(j=1;j<=m;j++){if((!vis[j]) && (dis[j]>dis[pos]+w[pos][j] || (dis[j]==dis[pos]+w[pos][j] && cost[j]>cost[pos]+mm[pos][j]))){dis[j]=dis[pos]+w[pos][j];cost[j]=cost[pos]+mm[pos][j];}} }cout << dis[t] << " " << cost[t] << endl;}return 0;}
代码运行情况
美美过了
感想
细心细心再细心。
最好还是给dijkstra单独写个函数,条件判断单独写一个函数吧,这次全放一起能看明白,下次题目更复杂就不一定了。
20211123 HDU练习 最短路和最小生成树相关推荐
- HDU 1301 Jungle Roads(裸最小生成树)
题目链接 今天做了好几个模版最小生成树...贴一个kurskral. 1 /* 2 HDU 1301 Jungle Roads 3 最小生成树Kurskal模版 4 */ 5 #include < ...
- 【挑战程序设计】- 2.5 图论(最短路、最小生成树)
2.5 图论(最短路.最小生成树) 文章目录 2.5 图论(最短路.最小生成树) 2.5.1 定义们 2.5.2 图的表示 2.5.3 图的搜索 2.5.4 最短路问题 单源1:bellman-for ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- Hdu 1217 最短路.cpp
题意: 各国的汇率兑换.. 给出各国之间汇率兑换的比例,然后问你是否可以通过不断地兑换最后挣钱.. 譬如美金兑换英镑 是0.5 英镑兑换法币是 10 法币兑换美金是 0.21 所以通过1美金兑换成0. ...
- hdu 5624 KK's Reconstruction(最小生成树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5624 解题思路: 题目中要求每个点都连通,且保证最大边与最小边的差值最小.可以想到的是利用最小生成树的 ...
- hdu 2112 HDU Today 最短路(Dijkstra算法)
HDU Today Time Limit: 15000/5000 MS ...
- hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)
还是畅通工程 Time Limit: 4000/2 ...
- hdu 2544 最短路 (dijkstra)
http://acm.hdu.edu.cn/showproblem.php?pid=2544 最简单的最短路了吧 改天试试优化版本的 #include<stdio.h> #include& ...
- hdu 1879 继续通畅工程(最小生成树)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1879 /************************************************* ...
最新文章
- centos7上的图形化界面svn客户端_Git实战一:图形客户端规范用法小讲
- eclipse 3.55安装j2ee开发工具
- Ghost网刻后window 7 sysprep无人值守应答文件制作
- Hive 数据压缩格式总结
- 如何用python做一个时钟_Python使用turtle库制作一个时钟
- 洛谷 P2466 Sue的小球 解题报告
- 如何学习Android驱动开发
- Arduino图形化编程
- 初窥windows SE7EN
- python爬虫抓取双色球_Python爬虫练习:爬取双色球每期的中奖号码,看能不能中奖...
- 职校高一计算机课高一,职高高一数学课件
- Bokeh Graph
- 安卓访客模式_如何设置Android访客模式以及为什么要这么做 | MOS86
- Django——model基础
- vue中使用v-html防止xss注入
- 抖音官网全面改版,网页版正式上线
- 如何恢复录音删除的录音文件_硬盘分区数据误删除如何恢复?文件删除不用急...
- [转载]使用Java编写Palm OS程序的解决方案
- Matlab机器人工具箱(0)——旋转与平移变换
- 工业设备数据采集调研要点