最短路+dp思路:nuoyanli 520 Let‘s play computer game

输入样例1:

10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3
 

输出样例1:

Time = 6: 5 => 4 => 8 => 3
Distance = 3: 5 => 1 => 3
 

输入样例2:

7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5
 

输出样例2:

Time = 3; Distance = 4: 3 => 2 => 5

这个nuoyanli 520 Let‘s play computer game 就是讲最短路+dp思路的,它可以满足例如这样的条件 “最快到达路线不唯一,则输出几条最快路线中最短的那条”

这样的话我们就可以采用两边最短路+dp就可以了

代码:

  1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cstring>
5 #include<cmath>
6 #include<algorithm>
7 #include<queue>
8 using namespace std;
9 typedef long long ll;
10 typedef unsigned long long ull;
11 const int MAXN=1000000;
12 const int MIN_INF=0x80000000;
13 const int MAX_INF=0x7fffffff;
14 int n,m;
15 int beg[505];
16 int to[505050];
17 int nex[505050];
18 int weight[505050];
19 int tisme[505050];
20 int e;
21 int st,ed;
22 bool vis[505];
23 int answ[505];
24 int anst[505];
25 int stepw[505];
26 int tarw[505];
27 int tart[505];
28 int answw[505];
29 int answwsize;
30 int anstt[505];
31 int ansttsize;
32
33 struct p{
34 int val;
35 int self;
36 int step;
37 bool operator <(const p &b)const{
38 return val>b.val;
39 }
40 };
41
42
43 priority_queue<p> q;
44 void init(){
45 e=0;
46 memset(beg,-1,sizeof(beg));
47 // answw="";
48 // anstt="";
49 return;
50 }
51 //Function area
52
53 void add(int a,int b,int w,int t){
54 nex[++e]=beg[a];
55 beg[a]=e;
56 to[e]=b;
57 weight[e]=w;
58 tisme[e]=t;
59 }
60
61 void Dijkstraw(int start){
62 q.push({0,start,0});
63 memset(vis,0,sizeof(vis));
64 memset(answ,0x3f3f3f3f,sizeof(answ));
65 memset(tarw,-1,sizeof(tarw));
66 memset(stepw,0x3f3f3f3f,sizeof(stepw));
67 answ[start]=0;
68 while(q.size()){
69 p now=q.top();
70 if(now.self==ed)
71 break;
72 q.pop();
73 if(vis[now.self])
74 continue;
75 vis[now.self]=true;
76 for(int i=beg[now.self];i!=-1;i=nex[i]){
77 int nx=to[i];
78 if(answ[nx]>now.val+weight[i]){
79 answ[nx]=now.val+weight[i];
80 q.push({now.val+weight[i],nx,now.step+1});
81 stepw[nx]=now.step+1;
82 tarw[nx]=now.self;
83 }
84 if(answ[nx]==now.val+weight[i]){
85 if(stepw[nx]>now.step+1){
86 q.push({now.val+weight[i],nx,now.step+1});
87 stepw[nx]=now.step+1;
88 tarw[nx]=now.self;
89 }
90 }
91 }
92 }
93 answwsize=0;
94 for(int i=ed;i!=st;i=tarw[i]){
95 answw[++answwsize]=i;
96 }
97 answw[++answwsize]=st;
98 }
99
100 void Dijkstrat(int start){
101 while(q.size())
102 q.pop();
103 q.push({0,start,0});
104 memset(vis,0,sizeof(vis));
105 memset(anst,0x3f3f3f3f,sizeof(anst));
106 memset(answ,0x3f3f3f3f,sizeof(answ));
107 memset(stepw,0x3f3f3f3f,sizeof(stepw));
108 memset(tart,-1,sizeof(tart));
109 answ[start]=0;
110 while(q.size()){
111 p now=q.top();
112 if(now.self==ed)
113 break;
114 q.pop();
115 if(vis[now.self])
116 continue;
117 vis[now.self]=true;
118 for(int i=beg[now.self];i!=-1;i=nex[i]){
119 int nx=to[i];
120 if(anst[nx]>now.val+tisme[i]){
121 anst[nx]=now.val+tisme[i];
122 answ[nx]=now.val+weight[i];
123 q.push({now.val+tisme[i],nx,now.step+1});
124 stepw[nx]=now.step+1;
125 tart[nx]=now.self;
126 }
127 if(anst[nx]==now.val+tisme[i]){
128 if(answ[nx]>now.val+weight[i]){
129 q.push({now.val+tisme[i],nx,now.step+1});
130 tart[nx]=now.self;
131 stepw[nx]=now.step+1;
132 }else if(answ[nx]==now.val+weight[i]){
133 if(stepw[nx]>now.step+1){
134 q.push({now.val+tisme[i],nx,now.step+1});
135 stepw[nx]=now.step+1;
136 tart[nx]=now.self;
137 }
138 }
139 }
140 }
141 }
142 ansttsize=0;
143 for(int i=ed;i!=st;i=tart[i]){
144 anstt[++ansttsize]=i;
145 }
146 anstt[++ansttsize]=st;
147 }
148 int main(){
149 ios::sync_with_stdio(false);
150 ios_base::sync_with_stdio(false);
151 cin.tie(0);
152 cout.tie(0);
153 init();
154 cin>>n>>m;
155 for(int i=1;i<=m;i++){
156 int a,b,c,d,e;
157 cin>>a>>b>>c>>d>>e;
158 if(c==1){
159 add(a,b,d,e);
160 }else{
161 add(a,b,d,e);
162 add(b,a,d,e);
163 }
164 }
165 cin>>st>>ed;
166 Dijkstraw(st);
167 int answww=answ[ed];
168 Dijkstrat(st);
169 cout<<"Time = "<<anst[ed];
170 bool flagttt=true;
171 if(answwsize==ansttsize){
172 for(int i=1;i<=answwsize;i++){
173 if(answw[i]!=anstt[i]){
174 flagttt=false;
175 break;
176 }
177 }
178 }else{
179 flagttt=false;
180 }
181 if(flagttt==true){
182 cout<<"; Distance = "<<answww;
183 cout<<": ";
184 // reverse(answw.begin(),answw.end());
185 for(int i=answwsize;i!=0;i--){
186 if(i!=answwsize)
187 cout<<" => ";
188 cout<<answw[i];
189 }
190 cout<<endl;
191 }else{
192 cout<<": ";
193 for(int i=ansttsize;i!=0;i--){
194 if(i!=ansttsize)
195 cout<<" => ";
196 cout<<anstt[i];
197 }
198 cout<<endl;
199 cout<<"Distance = "<<answww;
200 cout<<": ";
201 for(int i=answwsize;i!=0;i--){
202 if(i!=answwsize)
203 cout<<" => ";
204 cout<<answw[i];
205 }
206 cout<<endl;
207 }
208 }

不知道为啥我的这个代码错了一组样例(23分)

  1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<queue>
6 #include<vector>
7 using namespace std;
8 const int maxn=505;
9 #define INF 0x3f3f3f3f
10 struct shudui1
11 {
12 int start,value;
13 bool operator < (const shudui1 q)const
14 {
15 return value>q.value;
16 }
17 } str1;
18 struct shudui2
19 {
20 int start,value1,value2;
21 } str2;
22 int dis[maxn],path[maxn],dp[maxn],path1[maxn],vis[maxn],path2[maxn],len1,len2;
23 priority_queue<shudui1>r; //里面的数据默认是从小到大排序,这样就不用通过佛如循环遍历在每一次找v里面的最小值
24 vector <shudui2>w[maxn]; //将每一个起点的值作为数组的标识
25 //例如,1 2 3这一组数据,就是说1连接着2,那就把所有1能到的地方存到这个里面
26 void JK1(int s,int en)
27 {
28 memset(dp,INF,sizeof(dp));
29 memset(dis,INF,sizeof(dis));
30 memset(vis,0,sizeof(vis));
31 memset(path,-1,sizeof(path));
32 dp[s]=0;
33 dis[s]=0;
34 str1.start=s;
35 str1.value=0;
36 r.push(str1);
37 while(!r.empty())
38 {
39 int x,y;
40 str1=r.top();
41 r.pop();
42 x=str1.start;
43 y=str1.value;
44 if(vis[x]) continue;
45 vis[x]=1;
46 int len=w[x].size();
47 for(int i=0; i<len; ++i)
48 {
49 str2=w[x][i];
50 if(dis[x]+str2.value1<dis[str2.start])
51 {
52
53 dp[str2.start]=dp[x]+str2.value2;
54 dis[str2.start]=dis[x]+str2.value1;
55 path[str2.start]=x;
56 //printf("%d %d***\n",str2.start,x);
57 if(!vis[str2.start])
58 {
59 str1.start=str2.start;
60 str1.value=dis[str2.start];
61 r.push(str1);
62 }
63
64 }
65 else if(dis[x]+str2.value1==dis[str2.start])
66 {
67 if(dp[str2.start]>dp[x]+str2.value2)
68 {
69 //printf("%d %d***\n",str2.start,x);
70 path[str2.start]=x;
71 dp[str2.start]=dp[x]+str2.value2;
72 if(!vis[str2.start])
73 {
74 str1.start=str2.start;
75 str1.value=dis[str2.start];
76 r.push(str1);
77 }
78 }
79 }
80 }
81 }
82 }
83 void JK2(int s,int en)
84 {
85 memset(dp,INF,sizeof(dp));
86 memset(dis,INF,sizeof(dis));
87 memset(vis,0,sizeof(vis));
88 memset(path,-1,sizeof(path));
89 dp[s]=0;
90 dis[s]=0;
91 str1.start=s;
92 str1.value=0;
93 r.push(str1);
94 while(!r.empty())
95 {
96 int x,y;
97 str1=r.top();
98 r.pop();
99 x=str1.start;
100 y=str1.value;
101 if(vis[x]) continue;
102 vis[x]=1;
103 int len=w[x].size();
104 for(int i=0; i<len; ++i)
105 {
106 str2=w[x][i];
107 if(dis[x]+str2.value2<dis[str2.start])
108 {
109
110 dp[str2.start]=dp[x]+str2.value1;
111 dis[str2.start]=dis[x]+str2.value2;
112 path[str2.start]=x;
113 //printf("%d %d***\n",str2.start,x);
114 // if(!vis[str2.start])
115 // {
116 str1.start=str2.start;
117 str1.value=dis[str2.start];
118 r.push(str1);
119 // }
120
121 }
122 else if(dis[x]+str2.value2==dis[str2.start])
123 {
124 if(dp[str2.start]>dp[x]+str2.value1)
125 {
126 //printf("%d %d***\n",str2.start,x);
127 path[str2.start]=x;
128 dp[str2.start]=dp[x]+str2.value1;
129 // if(!vis[str2.start])
130 // {
131 str1.start=str2.start;
132 str1.value=dis[str2.start];
133 r.push(str1);
134 // }
135 }
136 }
137 }
138 }
139 }
140 int main()
141 {
142 int n,m;
143 scanf("%d%d",&n,&m);
144 while(m--)
145 {
146 int x,y,z1,z2,type;
147 scanf("%d%d%d%d%d",&x,&y,&type,&z1,&z2);
148 x++;
149 y++;
150 if(type)
151 {
152 //p[x][y]=z2;
153 str2.start=y;
154 str2.value1=z1;
155 str2.value2=z2;
156 w[x].push_back(str2);
157 }
158 else
159 {
160 //p[x][y]=p[y][x]=z2;
161 str2.start=y;
162 str2.value1=z1;
163 str2.value2=z2;
164 w[x].push_back(str2);
165 str2.start=x;
166 w[y].push_back(str2);
167 }
168 }
169 int st,en,short_dis,short_time;
170 scanf("%d%d",&st,&en);
171 st++;en++;
172 JK1(st,en);
173 short_dis=dis[en];
174 int temp=en;
175 while(temp!=-1)
176 {
177 path1[len1++]=temp;
178 temp=path[temp];
179 }
180
181 JK2(st,en);
182 short_time=dis[en];
183 temp=en;
184 while(temp!=-1)
185 {
186 path2[len2++]=temp;
187 temp=path[temp];
188 }
189 int flag=0;
190 if(len1==len2)
191 {
192 for(int i=0; i<len1; ++i)
193 {
194 if(path1[i]!=path2[i])
195 {
196 flag=1;
197 break;
198 }
199 }
200 }
201 else flag=1;
202
203 if(flag)
204 {
205 printf("Time = %d: %d",short_time,st-1);
206 for(int i=len2-2; i>=0; --i)
207 {
208 printf(" => %d",path2[i]-1);
209 }
210 printf("\n");
211
212 printf("Distance = %d: %d",short_dis,st-1);
213 for(int i=len1-2; i>=0; --i)
214 {
215 printf(" => %d",path1[i]-1);
216 }
217 printf("\n");
218 }
219 else
220 {
221 printf("Time = %d; Distance = %d: %d",short_time,short_dis,st-1);
222 for(int i=len1-2; i>=0; --i)
223 {
224 printf(" => %d",path1[i]-1);
225 }
226 printf("\n");
227 }
228 return 0;
229 }

L3-007 天梯地图 (30分) 最短路+dp的更多相关文章

  1. 天梯赛练习 L3-007 天梯地图 (30分) Dijkstra

    题目分析: 本题的题意比较清晰,就是有一个起点和一个终点,给出m条路径,可能是单向的可能是双向的,同时一条路有两个权重,分别是通过这条路需要的时间和这条路的路径长度,题目需要求出两条路径,一条是在最快 ...

  2. PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS

    PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...

  3. PAT 甲级 1045 Favorite Color Stripe (30 分)(思维dp,最长有序子序列)

    1045 Favorite Color Stripe (30 分)   Eva is trying to make her own color stripe out of a given one. S ...

  4. PAT-1111 Online Map (30分) 最短路+dfs

    明天就要考PAT,为了应付期末已经好久没有刷题了啊啊啊啊,今天开了一道最短路,状态不是很好 1.没有读清题目要求,或者说没有读完题目,明天一定要注意 2.vis初始化的时候从1初始化到n,应该从0开始 ...

  5. 【PAT甲级】1068 Find More Coins (30 分)(背包/DP)

    题意: 输入两个正整数N和M(N<=10000,M<=10000),接着输入N个正整数.输出最小的序列满足序列和为M. AAAAAccepted code: #define HAVE_ST ...

  6. CCCC L2-001 紧急救援 floyd改的dijkstra模板 (记录路径) L3 天梯地图

    https://www.patest.cn/contests/gplt/L2-001 题解:求最短路的条数,并输出点的权值最大的路径,用priority_queue会wa两个点,原因不明. 于是又学了 ...

  7. PTA 07-图5 Saving James Bond - Hard Version (30分)

    07-图5 Saving James Bond - Hard Version   (30分) This time let us consider the situation in the movie ...

  8. L3-007. 天梯地图

    L3-007. 天梯地图 题目链接:https://www.patest.cn/contests/gplt/L3-007 Dijstra 这题是Dijstra的变形,麻烦的是两种最短路的相同距离时的选 ...

  9. L3-015 球队“食物链” (30 分)

    L3-015 球队“食物链” (30 分)   某国的足球联赛中有N支参赛球队,编号从1至N.联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场. 联赛战罢,结果已经尘埃落定.此时,联赛主席 ...

随机推荐

  1. 计算机科学: 寄存器&内存

    参考: [十分钟速成课:计算机科学]6.寄存器&内存 要想聊寄存器Latch,首先要聊内存.什么是内存? Memory,就是储存信息的东西. 我们都玩过单机游戏,如果突然关机,游戏结束但是没有 ...

  2. Spring源码深度解析之事务

    Spring源码深度解析之事务 目录 一.JDBC方式下的事务使用示例 (1)创建数据表结构 (2)创建对应数据表的PO (3)创建表和实体之间的映射 (4)创建数据操作接口 (5)创建数据操作接口实 ...

  3. 如何跑通第一个 SQL 作业

    简介: 本文由阿里巴巴技术专家周凯波(宝牛)分享,主要介绍如何跑通第一个SQL. 一.SQL的基本概念 1.SQL 分类 SQL分为四类,分别是数据查询语言(DQL).数据操纵语言(DML).数据定义 ...

  4. 【windows】快捷键

    Ctrl+字母键 1.Ctrl+A:全选 2.Ctrl+C:复制选择的项目 3.Ctrl+E:选择搜索框 4.Ctrl+F:选择搜索框 5.Ctrl+N:创建新的项目 6.Ctrl+W:关闭当前窗口 ...

  5. JDBC入门程序总结

    JDBC本质 只是一个接口 每个数据库的规范 就是实现类的接口 其实是官方 定义的一套操作所有关系型数据库的规则,就是接口,各个数据库厂商去实现这套接口,提供数据库驱动jar包, 我们可以使用这套接口 ...

  6. 【易筋经】Llinux服务器初始化及常用命令大全

    Llinux服务器初始化及常用命令大全 1.关闭防火墙以及内核安全机制 systemctl stop firewalld systemctl disable firewalld ##永久性关闭 set ...

  7. wmic 查看主板信息

    查看主板信息的一个命令:wmic baseboard get 当然在命令提示符里查看,真的很费劲,所以我们将命令格式化一下:wmic baseboard get /format:HFORM >c ...

  8. SAP内表类型及其数据读取效率评估

    内表大概分3种: 1.标准表standard tables:如果不指定BINARY SEARCH附加选项,则默认为线性查找(linear search),既一条一条的查找. 2.排序表(sorted ...

  9. 基于.NET Core的优秀开源项目合集

    开源项目非常适合入门,并且可以作为体系结构参考的好资源, GitHub中有几个开源的.NET Core项目,这些项目将帮助您使用不同类型的体系结构和编码模式来深入学习 .NET Core技术, 本文列 ...

  10. 参数模型检验过滤器 .NetCore版

    最近学习 .NETCore3.1,发现过滤器的命名空间有变化. 除此以外一些方法的名称和使用方式也有变动,正好重写一下. 过滤器的命名空间的变化 原先:System.Web.Http.Filters; ...