欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > RoboCom 2021 编程技能赛决赛 7-4 猛犸不上 Ban

RoboCom 2021 编程技能赛决赛 7-4 猛犸不上 Ban

2025/4/21 2:24:06 来源:https://blog.csdn.net/m0_47587308/article/details/140880227  浏览:    关键词:RoboCom 2021 编程技能赛决赛 7-4 猛犸不上 Ban

7-4 猛犸不上 Ban

赛题

分数 30  作者 DAI, Longao  单位 杭州百腾教育科技有限公司

mammoth-gd01e31f27_640.png

在一个名叫刀塔的国家里,有一只猛犸正在到处跑着,希望能够用它的长角抛物技能来撞飞别人。已知刀塔国有 N 座城市,城市之间由 M 条道路互相连接,为了拦住这头猛犸,每条道路上设置了 Vi​ 人的团队。

这只猛犸从 S 号城市出发,它可以选择:

  1. 在不重复地经过若干条道路后回到 S 号城市;
  2. 在不重复地经过若干条道路后到达 T 号城市。

猛犸经过一条道路后,就会把路上的人全部撞飞。作为一头爱喝雪碧的仁慈的猛犸,自然希望尽可能的少撞飞人。请你帮忙计算一下在最优的选择下,最少需要撞飞多少人才能够到达目标城市?

输入格式:

输入第一行是四个正整数 N,M,S,T (2≤N≤500,1≤M≤10^5),表示有 N 个城市,M 条道路,猛犸从 S 号城市出发,可以选择到达 T 号城市。

接下来的 M 行,每行三个正整数 Xi​,Yi​,Vi​ (0≤Vi​≤100),表示从 Xi​ 号城市到 Yi​ 号城市有一条道路,道路上有 Vi​ 人的团队。道路可双向通行,城市编号从 1 开始,两个城市之间最多只有一条道路,且没有一条道路连接相同的城市。

数据保证两种选择里至少有一种是可行的。

输出格式:

输出两行,第一行是两个数字,分别对应上面的两种选择分别最少需要撞飞多少人。如果无论撞飞多少人都无法满足选择要求,则输出 -1

第二行是一个句子,如果第一种(回到原点)的选择比较好,就输出 Win!,否则输出Lose!

输入样例:

5 6 1 5
1 2 1
2 3 2
3 4 3
4 1 5
3 5 4
4 5 1

输出样例:

在这里给出相应的输出。例如:

11 6
Lose!

代码长度限制

16 KB

时间限制

800 ms

内存限制

64 MB

栈限制

8192 KB

思路

1.寻找最短路径问题。

2.第一种方式回到S城市,可以分解成:到了某相邻城市,然后再回来。

3.第二种方式,直接到T城市,可以看作S为原点,到T的最短路径。

4.第一种方式的最小值,应该为S和该相邻城市的直线距离与不走该直线,S和该城市的最短距离之和。

5.两种方式都可以使用dijkstra算法。

AC

//7-4 猛犸不上 Ban dijkstra算法#include <bits/stdc++.h>using namespace std;
int N,M,S,T;// N 个城市,M 条道路,从S城市出发,可以选择到达T城市
const int SIZE = 505;
#define ll long long
int g[SIZE][SIZE];//存储两个城市间的权重、人数
int x,y,v;
int d[SIZE];//从S出发,最短距离
bool dv[SIZE];//从S出发,最短距离,标记是否走过
bool dv2[SIZE][SIZE];//从S到T直线距离,标记是否走过
int pre[SIZE];//S节点的前置节点
const int big = 0x3f3f3f;//所有节点距离原始节点的最短距离
void dijkstra1() {int c=-1;//当前选中节点while(true) {c=-1;//选出当前未访问的最近节点,第一次时d[S]为0,自身最近for(int i=1; i<=N; i++) {if(!dv[i]&&(c==-1||d[i]<d[c])) {c=i;}}if(c==-1) {break;//均已经访问完}dv[c]=true;for(int i=1; i<=N; i++) {if(d[i]>d[c]+g[c][i]) {//若和当前节点相邻,会被标记处,且标记处最短的d[i]=d[c]+g[c][i];pre[i]=c;}}}
}//所有节点距离原始节点的不走最短距离的次最短距离
void dijkstra2(int xx) {int c=-1;//当前选中节点while(true) {c=-1;//选出当前未访问的最近节点,第一次时d[S]为0,自身最近for(int i=1; i<=N; i++) {if(!dv[i]&&(c==-1||d[c]>d[i])) {c=i;}}if(c==-1) {break;//均已经访问完}dv[c]=true;for(int i=1; i<=N; i++) {//如果当前节点到目标节点正好是不能走的那条路 if(dv2[c][i]) continue;if(d[i]>d[c]+g[c][i]) {//若和当前节点相邻,会被标记处,且标记处最短的d[i]=d[c]+g[c][i];}}}
}int main() {cin>>N>>M>>S>>T;//未告诉的说明不通,无限大memset(g,big,sizeof g);for(int i=1; i<=M; i++) {cin>>x>>y>>v;g[x][y]=g[y][x]=v;}memset(d,big,sizeof d);memset(dv,false,sizeof dv);//目标节点为初始节点d[S]=0;dijkstra1();int min1=d[T];int min2=big;//已经遍历完S到T的距离//下面判断S途径一个绕回来的距离for(int i=1; i<=N; i++) {//所有S的一级子节点if(pre[i]==S) {memset(d,big,sizeof d);memset(dv2,false,sizeof dv2);memset(dv,false,sizeof dv);dv2[S][i]=dv2[i][S]=true;//目标节点为初始节点d[i]=0;dijkstra2(S);min2=min(d[S]+g[i][S],min2);}}cout<< (min2>=big? -1 : min2)<<" "<<(min1>=big? -1 :min1)<<endl;cout<<(min2<min1?"Win!":"Lose!")<<endl;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词