路由选择(最短路,次短路,第三短路)

29 篇文章 1 订阅

路由选择

题目描述:
在网络通信中,经常需要求最短路径。但完全用最短路径传输有这样一个问题:如果最终在两个终端节点之间给出的最短路径只有一条。则在该路径中的任一个节点或链路出现故障时,信号传输将面临中断的危险。因此,对网络路由选择作了以下改进:
为任意两节点之间通信提供三条路径供其选择,即最短路径、第二最短路径和第三最短路径。
第一最短路径定义为:给定一个不含负回路的网络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,求给定两点间的第一、第二和第三最短路径。
输入描述:
输入: 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
输出:三条路径(从小到大输出),每条路径占一行,形式为:路径长度 始点…终点 (中间用一个空格分隔)
样例输入:
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
样例输出:
4 1 2 3 4 5
5 1 3 4 5
6 1 2 3 5

#include<iostream>
#include<cstring>
using namespace std;
int n,from,to,maxn,map[31][31];
int tot,pre[31],ans1,ans2,ans3;
int a1[31],a2[31],a3[31];
bool flag[31];
void print()
{
    cout<<ans1<<" ";
    for(int i=n;i>=1;i--)
    if(a1[i])
    cout<<a1[i]<<" ";
    cout<<endl;
    cout<<ans2<<" ";
    for(int i=n;i>=1;i--)
    if(a2[i])
    cout<<a2[i]<<" ";
    cout<<endl;
    cout<<ans3<<" ";
    for(int i=n;i>=1;i--)
    if(a3[i])
    cout<<a3[i]<<" ";
    return;
}
void work()
{
    int sum=0,tmp=to;
    if(tot<ans1)
    {
        if(a2[1])
        {
            for(int i=1;i<=n;i++)
            a3[i]=a2[i];
            ans3=ans2;
        }
        if(a1[1])
        {
            for(int i=1;i<=n;i++)
            a2[i]=a1[i];
            ans2=ans1;
        }
        ans1=tot;
        memset(a1,0,sizeof(a1));
        while(tmp)
        {
            a1[++sum]=tmp;
            tmp=pre[tmp];
        }
        return;
    }
    else if(tot<ans2)
    {
        if(a2[1])
        {
            for(int i=1;i<=n;i++)
            a3[i]=a2[i];
            ans3=ans2;
        }
        ans2=tot;
        memset(a2,0,sizeof(a2));
        while(tmp)
        {
            a2[++sum]=tmp;
            tmp=pre[tmp];
        }
        return;
    }
    else if(tot<ans3)
    {
        ans3=tot;
        memset(a3,0,sizeof(a3));
        while(tmp)
        {
            a3[++sum]=tmp;
            tmp=pre[tmp];
        }
        return;
    }
}
void search(int u)
{
    if(u==to)
    work();
    flag[u]=1;
    for(int v=1;v<=n;v++)
    if(map[u][v]!=maxn&&!flag[v])
    {
        tot+=map[u][v];pre[v]=u;flag[v]=1;
        search(v);
        tot-=map[u][v];pre[v]=0;flag[v]=0;
    }
}
int main()
{
    ans1=ans2=ans3=10000000;
    cin>>n>>from>>to>>maxn;
    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
      cin>>map[i][j];
    search(from);
    print();
    return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值