P1186 玛丽卡

P1186 玛丽卡

题目描述

麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。

因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。

在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。

麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。

玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。

编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。

输入输出格式

输入格式:

第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。

接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内是就能通过。

输出格式:

输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。

输入输出样例

输入样例#1:
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
输出样例#1:
27
既然不能走堵车的路,就删去这条边,先跑一边最短路记录路径后枚举每条边选择删除再跑一边SPFA
代码有点冗长,大佬的代码只有一边spfa,加特判(判断这否记录路径,是否删边)
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<queue>
  4 #include<cstring>
  5 
  6 using namespace std;
  7 const int MAXN = 1100;
  8 
  9 struct Edge{
 10     int to,nxt,w;
 11 }e[MAXN*MAXN/2];
 12 int head[MAXN];
 13 int dis[MAXN];
 14 int pre[MAXN];
 15 bool vis[MAXN];
 16 queue<int>q;
 17 int n,m,ans,cnt,p;
 18 
 19 void add(int u,int v,int w)
 20 {
 21     ++cnt;
 22     e[cnt].to = v;
 23     e[cnt].w = w;
 24     e[cnt].nxt = head[u];
 25     head[u] = cnt; 
 26 }
 27 
 28 void spfa()
 29 {
 30     memset(dis,0x3f,sizeof(dis));
 31     q.push(1);
 32     vis[1] = true;
 33     pre[1] = 0;
 34     dis[1] = 0;
 35     while (!q.empty())
 36     {
 37         int u = q.front();
 38         q.pop();
 39         for (int i=head[u]; i; i=e[i].nxt)
 40         {
 41             int v = e[i].to;
 42             int w = e[i].w;
 43             if (dis[v]>dis[u]+w)
 44             {
 45                 dis[v] = dis[u]+w;
 46                 pre[v] = u;
 47                 if (!vis[v])
 48                 {
 49                     q.push(v);
 50                     vis[v] = true;
 51                 }
 52             }
 53         }
 54         vis[u] = false;
 55     }
 56 }
 57 
 58 void spfa_2(int a,int b)
 59 {
 60     while (!q.empty()) q.pop();
 61     memset(dis,0x3f,sizeof(dis));
 62     memset(vis,0,sizeof(vis));
 63     q.push(1);
 64     vis[1] = true;
 65     dis[1] = 0;
 66     while (!q.empty())
 67     {
 68         int u = q.front();
 69         q.pop();
 70         for (int i=head[u]; i; i=e[i].nxt)
 71         {
 72             int v = e[i].to;
 73             int w = e[i].w;
 74             if ((u==a&&v==b) || (u==b&&v==a)) continue;
 75             if (dis[v]>dis[u]+w)
 76             {
 77                 dis[v] = dis[u]+w;
 78                 if (!vis[v])
 79                 {
 80                     q.push(v);
 81                     vis[v] = true;
 82                 }
 83             }
 84         }
 85         vis[u] = false;
 86     }
 87 }
 88 
 89 int main()
 90 {
 91     scanf("%d%d",&n,&m);
 92     for (int u,v,w,i=1; i<=m; ++i)
 93     {
 94         scanf("%d%d%d",&u,&v,&w);
 95         add(u,v,w);
 96         add(v,u,w);
 97     }
 98     spfa();
 99     p = n;
100     ans = dis[n];
101     while (pre[p] && p)
102     {
103         spfa_2(p,pre[p]);
104         ans = max(ans,dis[n]);
105         p = pre[p];
106     }
107     printf("%d",ans);    
108     return 0;
109 } 
原文地址:https://www.cnblogs.com/mjtcn/p/7041280.html