Lightoj 1281 New Traffic System (记忆化Dijkstra)

题意

给出若干个城市,城市和城市存在修好的道路,和存在一些没有修好的道路。要求你求出最多修d条路,求起点s到终点t的最短路径是 多少。
给出城市数量n,城市编号从0 ~ n - 1 . n < 1e4 .
给出修好的道路的条数m, 2 <= m <= 3 * 1e4 .
给出存在但未被修好的路的条数k , 1 <= k <= 1e4 .
最多修d条路, 0 <= d <= 10 .
求s城市到t城市的最多修d条路的情况下的最短路.

分析

考虑dijkstra算法,朴素的没有条件的求最短路,只要从起点拓展即可。这里要求中途可以修路,相当于我们多了一维进行更新。
dp[i][j] 表示到达i城市,已经修了j条路的时候的最短路径长度。

仍然用优先队列进行维护,每次取出最小的dp[i][j](前提是在队列里)。然后更新周围的节点。

注意点就是这个图是有向图,一开始当作无向图压了两次边导致了WA。

题目中有说from a to b 的都是有方向的,如果是无方向的话,题目应当描述成 between a and b.

代码

  1 #define rep(x,y,z) for(int x=y;x<z;x++)
  2 #define drep(x,y,z) for(int x=y;x>=z;x--)
  3 #define pb(x) push_back(x)
  4 #define mp(x,y) make_pair(x,y)
  5 #define fi first
  6 #define se second
  7
  8 #include <iostream>
  9 #include <stdio.h>
 10 #include <string.h>
 11 #include <algorithm>
 12 #include <vector>
 13 #include <queue>
 14 using namespace std;
 15
 16 const int N = 1e4 + 10;
 17 const int D = 15;
 18 const int inf = 0x3f3f3f3f;
 19
 20 int dp[N][D];
 21 bool mark[N][D];
 22 vector<pair<int,int> > ori[N];
 23 vector<pair<int,int> > cho[N];
 24 struct box{
 25     int pos , use , cost;
 26     box(){}
 27     box(int a , int b , int c){pos=a,use=b,cost=c;}
 28     bool operator < (const box & A) const {
 29         return cost > A.cost;
 30     }
 31 };
 32
 33 void init(){
 34     rep(i,0,N){ori[i].clear();cho[i].clear();}
 35     memset(dp,inf,sizeof(dp));
 36     memset(mark,0,sizeof(mark));
 37 }
 38
 39 int slove(int n ,int d){
 40     //
 41     dp[0][0] = 0;
 42     priority_queue<box> Q;
 43     Q.push(box(0,0,dp[0][0]));
 44     while(!Q.empty()){
 45         int pos = Q.top().pos;
 46         int use = Q.top().use;
 47         Q.pop();
 48         if(mark[pos][use]) continue;
 49         mark[pos][use] = 1;
 50         //
 51         //cout << pos << " " << use << " " << dp[pos][use] << endl;
 52         //debug
 53         if(pos == n - 1) break;
 54         //
 55         int osize = ori[pos].size();
 56         int csize = cho[pos].size();
 57         //
 58         rep(i,0,osize){
 59             int aim = ori[pos][i].fi , w = ori[pos][i].se;
 60             if(dp[aim][use] > dp[pos][use] + w){
 61                 dp[aim][use] = dp[pos][use] + w;
 62                 Q.push(box(aim,use,dp[aim][use]));
 63             }
 64         }
 65         if(use + 1 > d) continue;
 66         rep(i,0,csize){
 67             int aim = cho[pos][i].fi , w = cho[pos][i].se;
 68             if(dp[aim][use + 1] > dp[pos][use] + w){
 69                 dp[aim][use + 1] = dp[pos][use] + w;
 70                 Q.push(box(aim,use+1,dp[aim][use + 1]));
 71             }
 72         }
 73     }
 74     //
 75     int ans = inf;
 76     rep(i,0,d+1){ans = min(ans,dp[n-1][i]);}
 77     //
 78     return ans == inf ? -1 : ans;
 79 }
 80
 81 int main(){
 82     int t;
 83     scanf("%d",&t);
 84     rep(tt,1,t+1){
 85         init();
 86         int n , m , k , d;
 87         scanf("%d %d %d %d",&n,&m,&k,&d);
 88         rep(i,0,m){
 89             int a , b , d;
 90             scanf("%d %d %d",&a,&b,&d);
 91             ori[a].pb(mp(b,d));
 92             //ori[b].pb(mp(a,d));
 93         }
 94         rep(i,0,k){
 95             int a , b , d;
 96             scanf("%d %d %d",&a,&b,&d);
 97             cho[a].pb(mp(b,d));
 98             //cho[b].pb(mp(a,d));
 99         }
100         int ans = slove(n,d);
101         //
102         printf("Case %d: ",tt);
103         if(ans < 0) puts("Impossible");
104         else printf("%d\n",ans);
105     }
106     return 0;
107 }
时间: 2024-10-12 18:53:36

Lightoj 1281 New Traffic System (记忆化Dijkstra)的相关文章

1281 - New Traffic System

  PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB The country - Ajobdesh has a lot of problems in traffic system. As the Govt. is very clever (!), they made a plan to use only one way roads. Two cities s and t are the two m

lightoj 1011 Marriage Ceremonies (暴力)(记忆化dp,状压) 转

转载自:http://blog.csdn.net/xindoo/article/details/9173949 暴力TLE 1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 5 using namespace std; 6 7 int vis[17]; 8 int n, ans, sum; 9 int map[19][19]; 10 11 void dfs(int x) 12 { 1

LightOJ 1422 Halloween Costumes(记忆化搜索)

题意:给你n天分别要穿的衣服,可以套着穿,但是一旦脱下来就不能再穿了,问这n天要准备几件衣服. ================================================================================= #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> using

Light oj 1281 - New Traffic System 多状态最短路

题目大意:有向图,新计划的地铁,有k个计划新路,利用现有的铁路.k条新路和限定只能用d条新路,找出从0到n-1的最短路径 题目思路:用dist[u][use],储存使用use条新路,到达节点u的最短路径. #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<algorithm> #inc

HDU 1142 A Walk Through the Forest (Dijkstra + 记忆化搜索 好题)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6350    Accepted Submission(s): 2332 Problem Description Jimmy experiences a lot of stress at work these days, especial

LightOJ 1038 Race to 1 Again 期望 记忆化dp

题目链接:点击打开链接 1038 - Race to 1 Again PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Rimi learned a new thing about integers, which is - any positive integer greater than 1 can be divided by its divisors. So, he is now playin

HDU 1142 A Walk Through the Forest(dijkstra+记忆化DFS)

题意: 给你一个图,找最短路.但是有个非一般的的条件:如果a,b之间有路,且你选择要走这条路,那么必须保证a到终点的所有路都小于b到终点的一条路.问满足这样的路径条数 有多少,噶呜~~题意是搜了解题报告才明白的Orz....英语渣~ 思路: 1.1为起点,2为终点,因为要走ab路时,必须保证那个条件,所以从终点开始使用单源最短路Dijkstra算法,得到每个点到终点的最短路,保存在dis[]数组中. 2.然后从起点开始深搜每条路,看看满足题意的路径有多少条. 3.这样搜索之后,dp[1]就是从起

hdu 1142 A Walk Through the Forest (Dijkstra + 记忆化搜索)

A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5984    Accepted Submission(s): 2211 Problem Description Jimmy experiences a lot of stress at work these days, especial

动态规划、记忆化搜索、Dijkstra算法的总结

动态规划 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的.若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次.如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这