hdu 1595 find the longest of the shortest (Dijkstra+路径处理)

Problem Description

Marica is very angry with Mirko because he found a new girlfriend and she seeks revenge.Since she doesn't live in the same city, she started preparing for the long journey.We know for every road how many minutes it takes to come from one city to another.
Mirko overheard in the car that one of the roads is under repairs, and that it is blocked, but didn't konw exactly which road. It is possible to come from Marica's city to Mirko's no matter which road is closed.
Marica will travel only by non-blocked roads, and she will travel by shortest route. Mirko wants to know how long will it take for her to get to his city in the worst case, so that he could make sure that his girlfriend is out of town for long enough.Write a program that helps Mirko in finding out what is the longest time in minutes it could take for Marica to come by shortest route by non-blocked roads to his city.

Input

Each case there are two numbers in the first row, N and M, separated by a single space, the number of towns,and the number of roads between the towns. 1 ≤ N ≤ 1000, 1 ≤ M ≤ N*(N-1)/2. The cities are markedwith numbers from 1 to N, Mirko is located in city 1, and Marica in city N.
In the next M lines are three numbers A, B and V, separated by commas. 1 ≤ A,B ≤ N, 1 ≤ V ≤ 1000.Those numbers mean that there is a two-way road between cities A and B, and that it is crossable in V minutes.

Output

In the first line of the output file write the maximum time in minutes, it could take Marica to come to Mirko.

Sample Input

5 6
1 2 4
1 3 3
2 3 1
2 4 4
2 5 7
4 5 1

6 7
1 2 1
2 3 4
3 4 4
4 6 4
1 5 5
2 5 2
5 6 5

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

11
13
27


题目意思刚开始一直没有看懂,后来查别人的才知道,其实就是找到最短路,逐次删掉其中一边,再分别求最短路长度,最后找到所有最短路中最长的。

一定要有保存原来节点的数组,因为每次调用dijkstra,pre都会改变,而删除的边要用到原来的节点,之前没有想清楚,调试了一个多小时才发现,还是自己水平不行啊!!!

#include <iostream>
#include <memory.h>
#include <stdio.h>
#define NUM 1005
#define INF 0x3f3f3f3f

using namespace std;

int n;
int g[NUM][NUM];      //保存修改之后的图
int dis[NUM][NUM];    //保存原图
int vis[NUM];
int lowcost[NUM];
int pre[NUM];        //用来保存每一次求最短路前驱节点
int path[NUM];      //用来保存最开始求的最短路前驱节点

void Dijkstra(int beg)
{
    for(int i=1; i<=n; i++)
    {
        lowcost[i]=INF;
        vis[i]=false;
        pre[i]=-1;
    }
    lowcost[beg]=0;
    for(int j=1; j<=n; j++)
    {
        int k=-1;
        int Min=INF;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i] && lowcost[i]<Min)
            {
                Min=lowcost[i];
                k=i;
            }
        }
        if(k==-1)break;
        vis[k]=true;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i] && lowcost[k]+g[k][i]<lowcost[i])
            {
                lowcost[i]=lowcost[k]+g[k][i];
                pre[i]=k;
            }
        }
    }
}


void printPath(int i)
{
    if(i==1)
        return ;
    printPath(pre[i]);
    printf("%d->",i);
}
int main()
{
    int m,a,b,v;
    while(cin>>n>>m)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                g[i][j]=INF;
            }
            g[i][i]=0;
        }
        while(m--)
        {
            cin>>a>>b>>v;
            if(v<g[a][b])
            {
                g[a][b]=g[b][a]=v;
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                dis[i][j]=g[i][j];
            }
        }
        int tmp=n;
        Dijkstra(1);
        for(int i=1;i<=n;i++)
        {
            path[i]=pre[i];
        }
        //Dijkstra(1);
        int Max=-1;
        while(tmp!=1)
        {
            //printf("cut:%d-%d\n",tmp,path[tmp]);
            g[tmp][path[tmp]]=g[path[tmp]][tmp]=INF;
            //cout<<endl;
            Dijkstra(1);
            /*for(int i=1; i<=n; i++)   输出当前存储节点
            {
                cout<<"pre["<<i<<"]:"<<pre[i]<<endl;
            }*/
            //cout<<lowcost[n]<<endl;
            if(lowcost[n]>Max)
            {
                Max=lowcost[n];
            }
            g[tmp][path[tmp]]=g[path[tmp]][tmp]=dis[tmp][path[tmp]];
            tmp=path[tmp];
            //cout<<"tmp:"<<tmp<<endl;
        }
        cout<<Max<<endl;
    }
    return 0;
}


你可能感兴趣的:(ACM,最短路,杭电)