URAL

来源:互联网 发布:石全石美软件破解版 编辑:程序博客网 时间:2024/05/22 01:48
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.
Input
There are two positive integer numbers n andm in the first line, the number of towns and roads between them respectively(2 ≤ n ≤ 10 000; 1 ≤ m ≤ 100 000). Nextm 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.
Output
Output the smallest number of gear-modes changes on the way to Orlov's city.
Example
inputoutput
3 21 23 21 3
1
3 31 22 33 11 3
0

感觉是一个比较裸的最短路,不过当时我没做出来- -!

变形点就是:

1.路径的权值没有告诉你

2.没有二了- -

不过需要加一个数组说明一下当前节点的朝向

当朝向与边权不同的时候这个距离其实就是1,反之为0

很容易表达啊 nowdir[i]^w就可以啊

╮(╯▽╰)╭+++当时没做出来+++╮(╯▽╰)╭

还有一点,一开始的话,走任何节点都是不需要记录值的,所以你需要模拟spfa的第一步,出开始节点,入开始节点的链接节点,并且dist赋值为0;

行了 没了。。。。。。。。。。。。。

#include<bits/stdc++.h>using namespace std;struct aa{    int u,v,w,next;} save[200008];int pre[10086];int ans=0;int dist[10086];bool vis[10086];int n,m;int nowdir[10086];void add(int u,int v,int w){    save[ans].u=u;    save[ans].v=v;    save[ans].w=w;    save[ans].next=pre[u];    pre[u]=ans++;}void init(){    for(int i=1; i<=n; i++)    {        pre[i]=-1;        dist[i]=0x3f3f3f3f;        vis[i]=0;    }}void spfa(int s,int e){    queue<int>ycq;    dist[s]=0;    for(int i=pre[s]; i!=-1; i=save[i].next)    {        int v=save[i].v;        int w=save[i].w;        nowdir[v]=w;        dist[v]=0;        ycq.push(v);        vis[v]=1;    }    while(!ycq.empty())    {        int u=ycq.front();        ycq.pop();        vis[u]=0;        for(int i=pre[u]; i!=-1; i=save[i].next)        {            int v=save[i].v;            int w=save[i].w;            if(dist[v]>dist[u]+(nowdir[u]^w))            {                dist[v]=dist[u]+(nowdir[u]^w);                nowdir[v]=w;                if(!vis[v])                {                    vis[v]=1;                    ycq.push(v);                }            }        }    }    printf("%d\n",dist[e]);}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        init();        while(m--)        {            int u,v;            scanf("%d%d",&u,&v);            add(u,v,1);            add(v,u,0);        }        int a,b;        scanf("%d%d",&a,&b);        spfa(a,b);    }}