• codevs 1062 路由选择


    1062 路由选择

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

        在网络通信中,经常需要求最短路径。但完全用最短路径传输有这样一个问题:如果最终在两个终端节点之间给出的最短路径只有一条。则在该路径中的任一个节点或链路出现故障时,信号传输将面临中断的危险。因此,对网络路由选择作了以下改进:

    为任意两节点之间通信提供三条路径供其选择,即最短路径、第二最短路径和第三最短路径。

        第一最短路径定义为:给定一个不含负回路的网络D={V,A,W},其中V={v1,v2,…,vn},A为边的集合,W为权的集合,设P1是D中最短(v1,vn)路。称P1为D中最短(v1,vn)路径,如果D中有一条(v1,vn)路,P2满足以下条件:

    (1)P2≠P1;(2)D中不存在异于P1的路P,使得:

    (3)W(P1)≤W(P)<W(P2)

    则称P2为D的第二最短路径。

        第三最短路径的定义为:设P2是D中第二最短(v1,vn)路径,如果D中有一条(v1,vn)路P3满足以下条件:

    (1)P3≠P2并且P3≠P1;(2)D中不存在异于P1,P2的路P,使得:

    (3)W(P2)≤W(P)<W(P3)

    则称P3为D中第三最短路径。

        现给定一有N个节点的网络,N≤30,求给定两点间的第一、第二和第三最短路径。

    输入描述 Input Description

    输入:  n  S  T  Max   (每格数值之间用空格分隔)

            M11  M12  …  M1n

            M21  M22  …  M2n

                  …   … 

            Mn1  Mn2  …  Mnn

        其中,n为节点数,S为起点,T为终点,Max为一代表无穷大的整数,Mij描述I到J的距离,若Mij=Max,则表示从I到J无直接通路,Mii=0。

    输出描述 Output Description

    输出:三条路径(从小到大输出),每条路径占一行,形式为:路径长度 始点…终点  (中间用一个空格分隔)

    样例输入 Sample Input

    5  1       5     10000                               

    0         1         3         10000     7          

    10000     0          1         10000     10000       

    10000     10000     0         1         4

    10000     10000     10000     0        1

    10000     1         10000     10000     0

    样例输出 Sample Output

    4  1  2  3  4  5

    5  1  3  4  5

    6  1  2  3  5

    数据范围及提示 Data Size & Hint

     

    /*
    看完后以为是个k短路,然而路径不对
    而且还没看到可以相同短 
    后来发现n很小,可以用搜索做
    路径还是不对 改了好久才改对 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,len,topt,start,end,MAXN,first[500],m[50][50],ans[5],a[5][500],b[500],l[500];
    struct edge
    {
        int from;
        int to;
        int val;
        int next;
    }e[50*50];
    void add(int x,int y,int z)
    {
        topt++;
        e[topt].from=x;
        e[topt].to=y;
        e[topt].val=z;
        e[topt].next=first[x];
        first[x]=topt;
    }
    int judge(int x)
    {
        int i=1,j=1;
        while(i<=l[x]&&j<=len)
        {
            if(b[j]==a[x][j])
            {
                i++,j++;
                continue;
            }
            if(b[j]<a[x][i])return 1;
            return 0;
        }
        return len<l[x];
    }
    void dfs(int now,int dis)
    {
        int i,j,k;
        if(dis>=ans[3])return;
        if(now==end)
        {
            if(dis<ans[1]||(dis==ans[1]&&judge(1)))
            {
                ans[3]=ans[2];
                l[3]=l[2];
                for(i=1;i<=l[2];i++)
                  a[3][i]=a[2][i];
                ans[2]=ans[1];
                l[2]=l[1];
                for(i=1;i<=l[1];i++)
                  a[2][i]=a[1][i];
                ans[1]=dis;
                l[1]=len;
                for(i=1;i<=len;i++)
                  a[1][i]=b[i];
            }
            else
            if(dis<ans[2]||(dis==ans[2]&&judge(2)))
            {
                ans[3]=ans[2];
                l[3]=l[2];
                for(i=1;i<=l[2];i++)
                  a[3][i]=a[2][i];
                ans[2]=dis;
                l[2]=len;
                for(i=1;i<=len;i++)
                  a[2][i]=b[i];
            }
            else
            if(dis<ans[3]||(dis==ans[3]&&judge(3)))
            {
                ans[3]=dis;
                l[3]=len;
                for(i=1;i<=len;i++)
                  a[3][i]=b[i];
            }
            return;
        }
        for(i=first[now];i;i=e[i].next)
        {
            int t=e[i].to;
            b[++len]=t;
            dfs(t,dis+e[i].val);
            len--;
        }
    }
    int main()
    {
        int i,j,k;
        scanf("%d%d%d%d",&n,&start,&end,&MAXN);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                scanf("%d",&m[i][j]);
        for(i=1;i<=n;i++)
           for(j=n;j>=1;j--)
           if(m[i][j]!=0&&m[i][j]!=MAXN)
           add(i,j,m[i][j]);
        ans[1]=ans[2]=ans[3]=100;
        b[++len]=start;
        dfs(start,0);
         for(i=1;i<=3;i++)
        {
            printf("%d ",ans[i]);
            for(j=1;j<=l[i];j++)
            printf("%d ",a[i][j]);
            printf("
    ");
        }
        return 0;
    }
    /*********************************************************//*分割线*/
    /*
    以下是由求k短路的思路作的
    但貌似只能是严格的才行
    而且路径好像输出不对...... 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n,topt,start,end,MAXN,first[50],head[50],dis[50][5],f[50];
    queue<int>q;
    struct edge
    {
        int from;
        int to;
        int val;
        int next;
    }e[50*50],ee[50*50];
    void add(int x,int y,int z)
    {
        topt++;
        e[topt].from=x;
        e[topt].to=y;
        e[topt].val=z;
        e[topt].next=first[x];
        first[x]=topt;
        ee[topt].from=y;
        ee[topt].to=x;
        ee[topt].val=z;
        ee[topt].next=head[y];
        head[y]=topt;
    }
    void spfa()
    {
        int i,j,k;
        memset(dis,127/3,sizeof(dis));
        q.push(start);
        dis[start][1]=0;
        f[start]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            f[u]=0;
            for(i=first[u];i;i=e[i].next)
            {
                int t=e[i].to;
                if(dis[t][1]>dis[u][1]+e[i].val)
                {
                    dis[t][3]=dis[t][2];
                    dis[t][2]=dis[t][1];
                    dis[t][1]=dis[u][1]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
    
                if(dis[u][1]+e[i].val>dis[t][1]&&dis[t][2]>dis[u][1]+e[i].val)
                {
                    dis[t][3]=dis[t][2];
                    dis[t][2]=dis[u][1]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
    
                if(dis[u][1]+e[i].val>dis[t][2]&&dis[t][3]>dis[u][1]+e[i].val)
                {
                    dis[t][3]=dis[u][1]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
    
                if(dis[u][2]+e[i].val>dis[t][1]&&dis[t][2]>dis[u][2]+e[i].val)
                {
                    dis[t][3]=dis[t][2];
                    dis[t][2]=dis[u][2]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
    
                if(dis[u][2]+e[i].val>dis[t][2]&&dis[t][3]>dis[u][2]+e[i].val)
                {
                    dis[t][3]=dis[u][2]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
    
                if(dis[u][3]+e[i].val>dis[t][2]&&dis[t][3]>dis[u][3]+e[i].val)
                {
                    dis[t][3]=dis[u][3]+e[i].val;
                    if(!f[t])
                    {
                        q.push(t);
                        f[t]=1;
                    }
                }
            }
        }
    }
    void dfs(int now,int sum)
    {
        int i,j,k;
        if(sum==0)return;
        for(i=head[now];i;i=ee[i].next)
        {
            int t=ee[i].to;
            for(j=1;j<=3;j++)
            if(dis[t][j]+ee[i].val==sum)
            {
                dfs(t,dis[t][j]);
                break;
            }
        }
        printf("%d ",now);
    }
    int main()
    {
        int i,j,k;
        scanf("%d%d%d%d",&n,&start,&end,&MAXN);
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                int x;
                scanf("%d",&x);
                if(x!=0&&x!=MAXN)
                add(i,j,x);
            }
        }
        spfa();
    
        printf("%d ",dis[end][1]);
        printf("%d ",start);
        dfs(end,dis[end][1]);
        printf("
    ");
    
        printf("%d ",dis[end][2]);
        printf("%d ",start);
        dfs(end,dis[end][2]);
        printf("
    ");
        
        
        printf("%d ",dis[end][3]);
        printf("%d ",start);
        dfs(end,dis[end][3]);
        printf("
    ");
        
        return 0;
    }
  • 相关阅读:
    Java SE6调用动态编译
    代理模式——动态代理
    基于Eclipse的Hadoop应用开发环境配置
    利用java反射读取xml配置文件
    java nio小结
    RPC应用的java实现
    Struts2+Hibernate Update问题小结
    彻底解决hadoop0.20.203.0eclipseplugin插件安装
    Hadoop完全分布式配置
    (转)javamail发送带附件邮件
  • 原文地址:https://www.cnblogs.com/dingmenghao/p/5753425.html
Copyright © 2020-2023  润新知