URAL 1930 Ivan's Car

来源:互联网 发布:c类网络借3位子网划分 编辑:程序博客网 时间:2024/05/29 05:05

URAL 1930 Ivan’s Car

Time limit 1500 ms
Memory limit 65536 kB
OS Windows
Source Ural Regional School
Programming Contest 2012
Author Grigoriy Nazarov (prepared by Bulat Zaynullin)


Problem Description


The world is in danger! Awful earthquakes are detected all over the world. Houses are destroyed, rivers overflow the banks, it is almost impossible to move from one city to another. Some roads are still useful, but even they became too steep because of soil movements.
Fortunately, engineer Ivan has a car, which can go well uphill and downhill. But there are different gear-modes for movement up and down, so during the driving you have to change gear-modes all the time. Also engineer Ivan has a good friend –– geologist Orlov. Together they are able to invent a plan for world saving. But, unfortunately, geologist Orlov lives in another town.
Ivan wants to save the world, but gear-box in his car started to wear out, so he doesn’t know, how long he will be able to use it. Please help Ivan to save the world. Find a route to the Orlov’s town, such that Ivan will have to change gear-modes as few times as possible. In the beginning of the way Ivan can turn on any of gear-modes and you don’t have to count this action as a changing of gear-mode.

Problem Description(汉化)


世界正处于危险之中!全世界都发现可怕的地震。房屋被毁,河流漫过河岸,从一个城市搬到另一个城市几乎是不可能的。有些道路仍然有用,但即使是因为土壤运动,它们也变得过于陡峭。
幸运的是,工程师伊凡有一辆车,它能很好地上坡和下坡。但有不同的齿轮模式上下移动,所以在驾驶期间,你必须改变齿轮模式的所有时间。同时工程师伊凡有一个好朋友––地质学家奥尔洛夫。他们一起创造出一个拯救世界的计划。但不幸的是,地质学家奥尔洛夫住在另一个城镇。
伊凡想拯救世界,但他的汽车里的变速箱开始磨损,所以他不知道他能用多久。请帮助伊凡拯救世界。找一条通往奥尔洛夫镇的路线,这样伊凡就必须尽可能少地换齿轮。在开始的方式伊凡可以打开任何齿轮模式,你不必把这一行动作为一个齿轮模式的变化。

Input


There are two positive integer numbers n and m in the first line, the number of towns and roads between them respectively (2 ≤ n ≤ 10 000; 1 ≤ m ≤ 100 000). Next m lines contain two numbers each — numbers of towns, which are connected by road. Moreover, the first is the town, which is situated below, from which you should go uphill by this road. Every road can be used for traveling in any of two directions. There is at most one road between any two cities. In the last line there are numbers of two cities, in which Ivan and geologist Orlov live, respectively. Although the majority of roads were destroyed, Ivan knows exactly, that the way to geologist Orlov’s city exists.

Input(汉化)


有两个正整数n和m在第一线,一些城镇之间的道路,它们分别为(2≤N≤10 000;1≤M≤100 000)。下M线包含两个数字,每一个城镇的数目,它们是通过道路连接的。此外,第一个是位于下面的城镇,你应该从这条路上山。每条路都可以用来双向旅行。任何两个城市之间最多只有一条路。最后一行有两个城市,分别是伊凡和地质学家奥尔洛夫居住的城市。虽然大部分的道路都被毁了,但伊凡确切地知道,地质学家奥尔洛夫的城市的存在方式。

Output


Output the smallest number of gear-modes changes on the way to Orlov’s city.

Output(翻译)


输出从伊凡城市到奥尔洛夫的城市最少改变几次齿轮。

input

3 2
1 2
3 2
1 3

output

1


input

3 3
1 2
2 3
3 1
1 3

output

0

Submit

#include <iostream>#include <vector>#include <algorithm>#include <cstdio>#include <queue>#include <cstring>using namespace std;#define MAXN 10005#define INF 0x3f3f3f3fstruct node{    int w, to;//w是上下坡方向,to是路指向哪个城市};int N, M;int s, e;int i;vector<node>mp[MAXN];//因为直接开mp[MAXN][MAXN]太大会超内存,所以用vector来存连通的城市int visit[MAXN];//记录是否到达过此城市int dist[MAXN];//记录到达每个城市换过的齿轮数int w[MAXN];//记录到达每个城市时正在上坡还是下坡void solve()//类似bfs{    queue<int>q;    visit[s] = 1;    int Size = mp[s].size();//Size代表某个城镇有几条路通往其他城镇    for(i = 0; i < Size; i++)    {        int to = mp[s][i].to;        int ww = mp[s][i].w;        visit[to] = 1;        dist[to] = 0;//第一次不需要换齿轮        w[to] = ww;//到达to城镇时车的上下坡方向        q.push(to);    }    while(!q.empty())    {        int u = q.front();        q.pop();        visit[u] = 0;        Size = mp[u].size();        for(i = 0; i < Size; i++)        {            int to = mp[u][i].to;            int add = mp[u][i].w == w[u] ? 0 : 1;//假如车辆方向改变就要多换一次齿轮,反之不必换齿轮            w[to] = mp[u][i].w;//记录到达to城镇时车的方向            if(dist[to] > dist[u] + add)//如果有换齿轮更少的选择,就更新dist            {                dist[to] = dist[u] + add;                if(!visit[to])//如果to城镇没有被访问过,就进队列                {                    visit[to] = 1;                    q.push(to);                }            }        }    }}int main(){    while(~scanf("%d %d", &N, &M))    {        for(i = 0; i < M; i++)        {            int u, v;            scanf("%d %d", &u, &v);            node temp;//假如从u到v的方向是1,就让v到u的方向为-1            temp.w = 1, temp.to = v;            mp[u].push_back(temp);            temp.w = -1, temp.to = u;            mp[v].push_back(temp);        }        memset(visit, 0, sizeof(visit));        memset(dist, INF, sizeof(dist));        scanf("%d %d", &s, &e);        solve();        printf("%d\n", dist[e]);    }}
原创粉丝点击