玛丽卡

题目描述 Description

麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。

输入描述 Input Description

第一行有两个用空格隔开的数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分钟内是就能通过。

输出描述 Output Description

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

样例输入 Sample Input

5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10

样例输出 Sample Output

27

就是删边呗,先跑一边最短路,记下路径,枚举删路径上的边即可。
代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int size = 2000100;
int head[size],next[size],dist[size],pre[size];
bool use[size];
int n,m;
int tot = 1;
struct dc
{
    int t,d;
    bool flag;
}l[size];
deque < int > q;
void build(int f,int t,int d)
{
    l[tot].t = t;
    l[tot].d = d;
    next[tot] = head[f];
    head[f] = tot ++;
}
void spfa_first()
{
    for(int i = 1 ; i <= n ; i ++)
        dist[i] = 2147483641;
    dist[1] = 0;
    use[1] = 1;
    q.push_back(1);
    while(!q.empty())
    {
        int f = q.front();
        q.pop_front();
        use[f] = 0;
        for(int i = head[f] ; i ; i = next[i])
        {
            int t = l[i].t;
            if(dist[t] > dist[f] + l[i].d)
            {
                dist[t] = dist[f] + l[i].d;
                pre[t] = f;
                if(!use[t])
                {
                    use[t] = 1;
                    if(!q.empty())
                    {
                        if(t < q.front())
                            q.push_front(t);
                        else
                            q.push_back(t);
                    }
                    else
                        q.push_back(t);
                }
            }
        }
    }
}
int tot_t;
int num[size];
void dfs(int u)
{
    num[++tot_t] = u;
    if(pre[u])
        dfs(pre[u]);
}
void spfa()
{
    for(int i = 1 ; i <= n ; i ++)
        dist[i] = 2147483641;
    dist[1] = 0;
    use[1] = 1;
    q.push_back(1);
    while(!q.empty())
    {
        int f = q.front();
        q.pop_front();
        use[f] = 0;
        for(int i = head[f] ; i ; i = next[i])
        {
            int t = l[i].t;
            if(dist[t] > dist[f] + l[i].d && !l[i].flag)
            {
                dist[t] = dist[f] + l[i].d;
                if(!use[t])
                {
                    use[t] = 1;
                    if(!q.empty())
                    {
                        if(dist[t] < dist[q.front()])
                            q.push_front(t);
                        else
                            q.push_back(t);
                    }
                    else
                        q.push_back(t);
                }
            }
        }
    }
}
int read()
{
    int x = 0 , f = 1;
    char in = getchar();
    while(in < '0' || in > '9')
    {
        if(in == '-')
            f = -1;
        in = getchar();
    }
    while(in >= '0' && in <= '9')
    {
        x = x * 10 + in - '0';
        in = getchar();
    }
    return x * f;
}
int main()
{
    n = read() , m = read();
    for(int i = 1 ; i <= m ; i ++)
    {
        int f = read() , t = read() , d = read();
        build(f,t,d) , build(t,f,d);
    }
    spfa_first();
    dfs(n);
    int ans = 0;
    for(int i = tot_t ; i >= 1 ; i --)
    {
        int j;
        for(j = head[num[i]] ; j ; j = next[j])
            if(l[j].t == num[i-1])
                break;
        l[j].flag = 1;
        l[(j-1^1)+1].flag = 1;
        spfa();
        ans = max(ans,dist[n]);
        l[j].flag = 0;
        l[(j-1^1)+1].flag = 0;
    }
    printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章