L3-007 天梯地图 (30分) 最短路+dp
最短路+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的更多相关文章
- 天梯赛练习 L3-007 天梯地图 (30分) Dijkstra
题目分析: 本题的题意比较清晰,就是有一个起点和一个终点,给出m条路径,可能是单向的可能是双向的,同时一条路有两个权重,分别是通过这条路需要的时间和这条路的路径长度,题目需要求出两条路径,一条是在最快 ...
- PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS
PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...
- 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 ...
- PAT-1111 Online Map (30分) 最短路+dfs
明天就要考PAT,为了应付期末已经好久没有刷题了啊啊啊啊,今天开了一道最短路,状态不是很好 1.没有读清题目要求,或者说没有读完题目,明天一定要注意 2.vis初始化的时候从1初始化到n,应该从0开始 ...
- 【PAT甲级】1068 Find More Coins (30 分)(背包/DP)
题意: 输入两个正整数N和M(N<=10000,M<=10000),接着输入N个正整数.输出最小的序列满足序列和为M. AAAAAccepted code: #define HAVE_ST ...
- CCCC L2-001 紧急救援 floyd改的dijkstra模板 (记录路径) L3 天梯地图
https://www.patest.cn/contests/gplt/L2-001 题解:求最短路的条数,并输出点的权值最大的路径,用priority_queue会wa两个点,原因不明. 于是又学了 ...
- 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 ...
- L3-007. 天梯地图
L3-007. 天梯地图 题目链接:https://www.patest.cn/contests/gplt/L3-007 Dijstra 这题是Dijstra的变形,麻烦的是两种最短路的相同距离时的选 ...
- L3-015 球队“食物链” (30 分)
L3-015 球队“食物链” (30 分) 某国的足球联赛中有N支参赛球队,编号从1至N.联赛采用主客场双循环赛制,参赛球队两两之间在双方主场各赛一场. 联赛战罢,结果已经尘埃落定.此时,联赛主席 ...
随机推荐
- Java并发包源码学习系列:ReentrantReadWriteLock读写锁解析
目录 ReadWriteLock读写锁概述 读写锁案例 ReentrantReadWriteLock架构总览 Sync重要字段及内部类表示 写锁的获取 void lock() boolean writ ...
- windows下使用mingw和msvc静态编译Qt5.15.xx
windows下使用mingw和msvc静态编译Qt5.15.xx 下载并安装相关依赖软件 Python version 2.7 https://www.python.org/downloads/ ( ...
- mysql的导入
方法1 load data [local] infile 'filename' into table tablename[option] ields terminated by 'string'(字段 ...
- LeetCode543.二叉树的直径
题目 1 class Solution { 2 public: 3 int minimum = INT_MIN; 4 vector<int>res; 5 int diameterOfBin ...
- 十一、UART&TTY驱动
Linux系统中UART驱动和TTY驱动两者有着紧密的关系,它们不像I2C和SPI驱动是单独一个模块,分析时应当将它们看成一个整体来分析.UART驱动部分依赖于硬件平台,而TTY驱动和具体的平台无关. ...
- 利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序
对Socket的一点个人理解:Socket原意是指插座.家家户户都有五花八门的家用电器,但它们共用统一制式的插座.这样做的好处就是将所有家用电器的通电方式统一化,不需要大费周章地在墙壁上凿洞并专门接电 ...
- Nginx报504 gateway timeout错误的解决方法(小丑搞笑版。。。)
一.今天登录我的网站,突然发现报了下面的一个错误: 我的第一反应是:超时了应该是Nginx代理没有设置超时时间,默认的超时时间估计太小了,然后就按照正常的方式用Xshell连接服务器,应该是网络或者是 ...
- SpringBoot深入理解
SpringBoot深入理解 项目打包SpringBoot启动过程 当使用打包时,会下载org-springframework-boot-loader的jar,并且不会放在lib存放的第三方jar包文 ...
- Golang 单元测试:有哪些误区和实践?
https://mp.weixin.qq.com/s/k8WNWpCIVl4xTmP3TQ_gxQ
- Linux监控内核SNMP计数器
nstat命令和rtacct命令是一个简单的监视内核的SNMP计数器和网络接口状态的实用工具. 语法 nstat/rtacct (选项) 选项 -h:显示帮助信息: -V:显示指令版本信息: -z:显 ...