齐头并进(51Nod-1649)

题目

在一个叫奥斯汀的城市,有n个小镇(从1到n编号),这些小镇通过m条双向火车铁轨相连。当然某些小镇之间也有公路相连。为了保证每两个小镇之间的人可以方便的相互访问,市长就在那些没有铁轨直接相连的小镇之间建造了公路。在两个直接通过公路或者铁路相连的小镇之间移动,要花费一个小时的时间。

现在有一辆火车和一辆汽车同时从小镇1出发。他们都要前往小镇n,但是他们中途不能同时停在同一个小镇(但是可以同时停在小镇n)。火车只能走铁路,汽车只能走公路。

现在请来为火车和汽车分别设计一条线路;所有的公路或者铁路可以被多次使用。使得火车和汽车尽可能快的到达小镇n。即要求他们中最后到达小镇n的时间要最短。输出这个最短时间。(最后火车和汽车可以同时到达小镇n,也可以先后到达。)

输入

单组测试数据。
第一行有两个整数n 和 m (2≤n≤400, 0≤m≤n*(n-1)/2) ,表示小镇的数目和铁轨的数目。
接下来m行,每行有两个整数u 和 v,表示u和v之间有一条铁路。(1≤u,v≤n, u≠v)。
输入中保证两个小镇之间最多有一条铁路直接相连。

输出

输出一个整数,表示答案,如果没有合法的路线规划,输出-1。

输入样例

4 2
1 3
3 4

输出样例

2

思路:两遍 Dijkstra 求两次的最大值即可

源程序

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 1000+5;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
using namespace std;


int n,m;
struct Edge { //边
    int from;//下一条边的编号
    int to;//边到达的点
    int dis;//边的长度
    Edge(int f,int t,int d) { //构造函数
        from=f;
        to=t;
        dis=d;
    }
};

struct HeapNode { //Dijkstra用到的优先队列的结点
    int dis;//点到起点距离
    int u;//点的序号
    HeapNode(int a,int b) {
        dis=a;
        u=b;
    }
    bool operator < (const HeapNode &rhs) const  {
        return dis > rhs.dis;
    }
};

struct Dijkstra {
    int n,m;//点数、边数,均从0开始
    vector edges;//边列表
    vector G[N];//每个结点出发的边的编号
    bool vis[N];//是否走过
    int dis[N];//起点s到各点的距离
    int p[N];//从起点s到i的最短路中的最后一条边的编号

    void init(int n) {//初始化
        this->n = n;
        for(int i=0; i Q;//优先队列
        Q.push(HeapNode(0,s));
        while(!Q.empty()) {
            HeapNode x=Q.top();
            Q.pop();

            int u=x.u;
            if(vis[u])//若已被访问
                continue;

            vis[u]=true;//标记为已访问
            for(int i=0; i dis[u]+e.dis) {//更新距离
                    dis[e.to] = dis[u]+e.dis;
                    p[e.to]=G[u][i];
                    Q.push(HeapNode(dis[e.to],e.to));
                }
            }
        }
        return dis[n];
    }
} DJ;
int mp[N][N];
int main() {
    scanf("%d%d",&n,&m);

    DJ.init(n);//初始化
    for(int i=0; i

 

你可能感兴趣的:(#,51Nod,#,图论——最短路)