uva 11374(Dijkstra) HappyNewYear!!!

2013年最后一题,也是最后一篇随笔~祝大家新年快乐!

题意:在一张无向图中, 有两种公交线路,快线和慢线。现在有一个人想要从s->e但是他只有一张快线车票。所以快线只能乘坐一次,慢线可以随便乘坐,让你求从s->e的最短路。

思路:这道题是liurujia书上的一题。没有按照他的方法做直接暴力出来了。方法就是每次向图中加一条边,然后对其求最短路,判断能不能更新当前最优值,可以的话把路径和答案记录下来即可。最后递归输出。

代码如下:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <algorithm>
  7 #include <queue>
  8 #include <stack>
  9 #include <vector>
 10 #define PB(a) push_back(a)
 11 #define MP(a, b) make_pair(a, b)
 12 
 13 using namespace std;
 14 
 15 typedef long long ll;
 16 typedef pair<int, int> pii;
 17 
 18 const int INF = 0x3f3f3f3f;
 19 const double eps = 1e-6;
 20 const int LEN = 1010;
 21 
 22 vector<pii> Map[LEN];
 23 int n, m, K, dis[LEN], pre[LEN], apre[LEN], stans, e;
 24 
 25 void Dijkstra(int s)
 26 {
 27     priority_queue<pii, vector<pii>, greater<pii> > q;
 28     int vis[LEN] = {0};
 29     for(int i=1; i<=n; i++)dis[i] = INF;
 30     dis[s] = 0;
 31     q.push(MP(dis[s], s));
 32     while(!q.empty()){
 33         pii nvex = q.top(); q.pop();
 34         int nv = nvex.second;
 35         if(vis[nv])continue;
 36         vis[nv] = 1;
 37         for(int i=0; i<Map[nv].size(); i++){
 38             int x = Map[nv][i].first, y = Map[nv][i].second;
 39             if(dis[x]>dis[nv]+y){
 40                 dis[x] = dis[nv]+y;
 41                 pre[x] = nv;
 42                 q.push(MP(dis[x], x));
 43             }
 44         }
 45     }
 46 }
 47 
 48 void Upans(int &ans, int pos){
 49     if(dis[e]>=ans)return ;
 50     ans = dis[e];
 51     stans = pos;
 52     for(int i=1; i<=n; i++)apre[i] = pre[i];
 53 }
 54 
 55 void outans(int vex, int s){
 56     if(vex==s)printf("%d", vex);
 57     else if(dis[vex]==0)return ;
 58     else{
 59         outans(apre[vex], s);
 60         printf(" %d", vex);
 61     }
 62 }
 63 
 64 int main()
 65 {
 66 //    freopen("in.txt", "r", stdin);
 67 
 68     int a, b, c, s;
 69     for(int kase=0; scanf("%d%d%d", &n, &s, &e)!=EOF ;kase++){
 70         memset(apre, 0 ,sizeof apre);
 71         if(kase)printf("\n");
 72         for(int i=0; i<=n; i++)Map[i].clear();
 73         scanf("%d", &m);
 74         for(int i=0; i<m; i++){
 75             scanf("%d%d%d", &a, &b, &c);
 76             Map[a].PB(MP(b,c));
 77             Map[b].PB(MP(a,c));
 78         }
 79         scanf("%d", &K);
 80         Dijkstra(s);
 81         int ans = dis[e]; stans = -1;
 82         for(int i=1; i<=n; i++)apre[i] = pre[i];
 83         for(int i=0; i<K; i++){
 84             scanf("%d%d%d", &a, &b, &c);
 85             Map[a].PB(MP(b, c));
 86             Dijkstra(s);
 87             Upans(ans, a);
 88             Map[a].pop_back();
 89             Map[b].PB(MP(a, c));
 90             Dijkstra(s);
 91             Upans(ans, b);
 92             Map[b].pop_back();
 93         }
 94 
 95         outans(e, s);printf("\n");
 96         if(stans==-1)printf("Ticket Not Used\n");
 97         else printf("%d\n", stans);
 98         printf("%d\n", ans);
 99     }
100     return 0;
101 }
View Code

 

转载于:https://www.cnblogs.com/shu-xiaohao/p/3500168.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值