P1186 玛丽卡

题目描述

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

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

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

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

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

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

输入输出格式

输入格式:

 

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

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

 

输出格式:

 

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

 

输入输出样例

输入样例#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

Solution:

  本题比较板子。

  题意中最多只有一条边无法通行,所以我们先求出最短路,若无法通行的路径不属于最短路则不会影响最短路,显然不会是最坏情况,所以最坏情况一定是最短路上的某条边无法通行,具体是哪一条,反正数据那么小直接枚举嘛,用配对堆优化dijkstra加个point_iterator就好了,这样写dijkstra的最坏时间复杂度$O(n^2log n)$对于本题数据完全能过。

代码:

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
using namespace __gnu_pbds;
const int N=1005,M=2000005;
int n,m,to[M],net[M],w[M],h[N],dis[N],cnt,pre[N],f,ans;
bool ct[N][N];
struct node{
    int u,d;
    node(int a=0,int b=0){u=a,d=b;}
    bool operator<(const node &a) const{return d>a.d;}
};
typedef __gnu_pbds::priority_queue<node,less<node>,pairing_heap_tag> heap;
heap q;
heap::point_iterator id[N];

il int gi(){
    int a=0;char x=getchar();
    while(x<'0'||x>'9')x=getchar();
    while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
    return a;
}

il void add(int u,int v,int c){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,w[cnt]=c;}

il void spfa(){
    For(i,1,n) id[i]=0,dis[i]=0x7fffffff;
    dis[1]=0;
    q.push(node(1,0));
    while(!q.empty()){
        node x=q.top();q.pop();
        for(int i=h[x.u];i;i=net[i])
            if(dis[to[i]]>dis[x.u]+w[i]&&!ct[x.u][to[i]]){
                dis[to[i]]=dis[x.u]+w[i];
                if(!f)pre[to[i]]=x.u;
                if(id[to[i]]==0) id[to[i]]=q.push(node(to[i],dis[to[i]]));
                else q.modify(id[to[i]],node(to[i],dis[to[i]]));
            }
    }
}

int main(){
    n=gi(),m=gi();
    int u,v,c;
    while(m--){
        u=gi(),v=gi(),c=gi();
        add(u,v,c),add(v,u,c);
    }
    spfa(),f=1;
    for(int i=n;i!=1;i=pre[i]){
        ct[pre[i]][i]=ct[i][pre[i]]=1;
        spfa();
        ct[pre[i]][i]=ct[i][pre[i]]=0;
        ans=max(ans,dis[n]);
    }
    cout<<ans;
    return 0;
}