51Nod-1649-齐头并进

来源:互联网 发布:花呗充值话费的淘宝店 编辑:程序博客网 时间:2024/06/15 02:56

ACM模版

描述

描述

题解

其实这个题放在二级是有理由的,只不过有坑点而已。一开始看到这个题我很懵逼,怎么避免同时停靠在一个城市呢?如果出现这样的情况,如何绕路才是最好的方案呢?

想了一会儿,才发现,想多了……根据题目,我们知道,凡是两个没有火车道直接连通的城市都会建公交。那么从起点通过两种交通方式到达同一个城市,一定是有一种一步便可以到达,另一种则需要多走几步。那么,不管这同一个城市是在途中还是终点,都不可能存在同时停靠的情况(走最短路的前提下)。所以,直接两边最短路搜索就可以了。BFS 好像也是可以的哦。

代码

#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 405;int n, m;bool vis[MAXN];int dis[MAXN];int train[MAXN][MAXN];int bus[MAXN][MAXN];void init(){    memset(train, 0x3f, sizeof(train));    memset(bus, 0x3f, sizeof(bus));}void dijkstra(int map[][MAXN]){    memset(dis, 0x3f, sizeof(dis));    memset(vis, 0, sizeof(vis));    dis[1] = 0;    for (int i = 1; i <= n; i++)    {        int tmp = INF, k = -1;        for (int j = 1; j <= n; j++)        {            if (!vis[j] && tmp > dis[j])            {                tmp = dis[j];                k = j;            }        }        if (tmp == INF)        {            break;        }        vis[k] = true;        for (int j = 1; j <= n; j++)        {            if (!vis[j] && dis[j] > dis[k] + map[k][j])            {                dis[j] = dis[k] + map[k][j];            }        }    }}int main(){    while (scanf("%d%d", &n, &m) != EOF)    {        init();        int a, b;        for (int i = 0; i < m; i++)        {            scanf("%d%d", &a, &b);            train[a][b] = train[b][a] = 1;        }        for (int i = 1; i <= n; i++)        {            for (int j = i + 1; j <= n; j++)            {                if (train[i][j] == INF)                {                    bus[i][j] = bus[j][i] = 1;                }            }        }        dijkstra(train);        int ans1 = dis[n];        dijkstra(bus);        int ans2 = dis[n];        int ans = max(ans1, ans2);        printf("%d\n", ans == INF ? -1 : ans);    }    return 0;}
原创粉丝点击