zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    免费下载 80多种的微软推出入门级 .NET视频
    和付费网盘说再见,自己搭建个人网盘(Java 开源项目)
    JS惰性删除和定时删除可过期的localStorage缓存,或sessionStorage缓存
    docker——系列文章
    Bash 脚本教程
    Sublime text3里 修改TAB键为缩进为四个空格
    百度网盘不限速,直接获取直链
    技术党适合做浏览器首页的网站
    常用电脑软件
    有哪些开源的 Python 库让你相见恨晚?
  • 原文地址:https://www.cnblogs.com/ticsmtc/p/6105109.html
Copyright © 2011-2022 走看看