瑪麗卡

題目描述 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章