zoukankan      html  css  js  c++  java
  • Reverse a Road 最短路

    Reverse a Road

    Time Limit 1000ms

    Memory Limit 65536K

    description

      Peter resides in the city of Nanuh, and goes to his working place in this city every weekday.He has been totally annoyed with the road traffic of this city. All the roads in this city are one-way, so he has to drive a longer way than he thinks he need.	One day, the following thought has come up to Peter’s mind: “How about making the sign of one road indicate the opposite direction? I think my act won’t be out as long as I change just one sign. Well, of course I want to make my route to the working place shorter as much as possible. Which road should I alter the direction of?” What a clever guy he is.	You are asked by Peter to write a program that finds the shortest route when the direction of up to one road is allowed to be altered. You don’t have to worry about the penalty for complicity, because you resides in a different country from Peter and cannot be punished by the law of his country. So just help him!
    							

    input

      The input consists of a series of datasets, each of which is formatted as follows:
    N
    S T
    M
    A1 B1
    A2 B2
    : : :
    AM BM	
    ,N denotes the number of points. S and T indicate the points where Andrew’s home and working place are located respectively. M denotes the number of roads. Finally, Ai and Bi indicate the starting and ending points of the i-th road respectively. Each point is identified by a unique number from 1 to N. Some roads may start and end at the same point. Also, there may be more than one road connecting the same pair of starting and ending points.	You may assume all the following: 1 <= N <= 1000, 1 <= M <= 10000, and S , T. 
    							

    output

      For each dataset, print a line that contains the shortest distance (counted by the number of passed roads) and the road number whose direction should be altered. If there are multiple ways to obtain the shortest distance, choose one with the smallest road number. If no direction change results in a shorter route, print 0 as the road number.	Separate the distance and the road number by a single space. No extra characters are allowed.
    							

    sample_input

    4
    1 4
    4
    1 2
    2 3
    3 4
    
    4 1
    							

    sample_output

    1 4
    							
    ----------------------------------------------------------

    求出起点到每个点的最短路dist[i],反向求出终点到每个点的最短路dist0[i],枚举每条边(u,v) dist[v]+dist0[u]+1的最小值即答案。

    ----------------------------------------------------------

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=1111;
    const int maxm=111111;
    const int OO=1e9;
    
    struct EDGE
    {
        int to;
        int w;
        int next;
    }edges[maxm],edges0[maxm];
    
    struct COCO{
        int u;
        int v;
        int w;
    }coco[maxm];
    int lk;
    
    int node,src,dest,edge;
    int head[maxn],dist[maxn];
    int head0[maxn],dist0[maxn],edge0;
    
    void prepare(int _node,int _src=0,int _dest=0)
    {
        node=_node,src=_src,dest=_dest;
        for (int i=0; i<=node; i++) head[i]=-1,head0[i]=-1;
        edge=0;
        edge0=0;
        lk=0;
    }
    
    void addedge(int u,int v,int c)
    {
        edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    
    void addedge0(int u,int v,int c)
    {
        edges0[edge0].w=c,edges0[edge0].to=v,edges0[edge0].next=head0[u],head0[u]=edge0++;
    }
    
    bool spfa(int node,int src,int head[],EDGE edges[],int dist[])
    {
        int i,l,r,u,v,w;
        bool visit[maxn];
        int q[maxn],outque[maxn];
        memset(visit,0,sizeof(visit));
        memset(outque,0,sizeof(outque));
        for (int i=0; i<=node; i++) dist[i]=OO;
        r=0;
        q[r++]=src;
        dist[src]=0;
        visit[src]=true;
        for (l=0; l!=r; ( (++l>=maxn)?(l=0):(1) ))
        {
            u=q[l];
            visit[u]=false;
            outque[u]++;
            if (outque[u]>node) return false;
            for (i=head[u]; i!=-1; i=edges[i].next)
            {
                v=edges[i].to;
                w=edges[i].w;
                if (dist[u]+w<dist[v])
                {
                    dist[v]=dist[u]+w;
                    if (visit[v]) continue;
                    q[r++]=v;
                    visit[v]=true;
                    if (r>=maxn) r=0;
                }
            }
        }
        return true;
    }
    
    void dijkstra(int n,int src,int dist[],int head[],EDGE edges[])
    {
        int _min,u,v,w;
        bool visit[maxn]={0};
        for (int i=1;i<=n;i++)
        {
            dist[i]=OO;
        }
        dist[src]=0;
        for (int loop=1; loop<=n; loop++)
        {
            u=0;
            _min=OO;
            for (int i=1; i<=n; i++)
            {
                if (!visit[i]&&dist[i]<_min)
                {
                    _min=dist[i];
                    u=i;
                }
            }
            if (u==0) return;
            visit[u]=true;
            for (int i=head[u];i!=-1;i=edges[i].next)
            {
                v=edges[i].to;
                w=edges[i].w;
                if (!visit[v]&&dist[u]+w<dist[v])
                {
                    dist[v]=dist[u]+w;
                }
            }
        }
    }
    
    int main()
    {
        int n,s,t,m;
        while (~scanf("%d",&n))
        {
            scanf("%d%d",&s,&t);
            prepare(n,s,t);
            scanf("%d",&m);
            while (m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                addedge(u,v,1);
                addedge0(v,u,1);
    
                coco[lk].u=u;
                coco[lk].v=v;
                coco[lk++].w=1;
            }
            spfa(n,s,head,edges,dist);
            spfa(n,t,head0,edges0,dist0);
    
            //dijkstra(n,s,dist,head,edges);
            //dijkstra(n,t,dist0,head0,edges0);
    
            int _min=dist[t];
            int ans=-1;
            for (int i=0;i<lk;i++)
            {
                int u,v,w;
                u=coco[i].u;
                v=coco[i].v;
                w=coco[i].w;
                if (dist[v]+dist0[u]+w<_min)
                {
                    _min=dist[v]+dist0[u]+w;
                    ans=i;
                }
            }
            printf("%d %d\n",_min,ans+1);
        }
    
        return 0;
    }
    











  • 相关阅读:
    DPDK 多进程
    dpdk helloword
    dpdk-ring-ping
    【基于python实现UI自动化】3.0 selenium
    算法题:实现 strStr()函数
    python程序设计:某体操比赛共有10名运动员参加,12名评委将根据运动员表现进行评分(满分10分),请编写Python程序,解决下列问题:
    Scrapy框架实战(五):通用爬虫 CrawlSpider
    python爬虫爬取_高德地图_主要城市迁徙意愿排行榜_19年至今数据
    年轻就该多尝试,教你20小时Get一项新技能
    LeetCode:283.移动零——简单
  • 原文地址:https://www.cnblogs.com/cyendra/p/3038383.html
Copyright © 2011-2022 走看看