最短路

1062 路由选择

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
</pre><div class="well" style="box-sizing: border-box; min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: rgb(237, 241, 242); border: 1px solid rgb(222, 229, 231); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; -webkit-box-shadow: rgba(0, 0, 0, 0.0470588) 0px 1px 1px inset; box-shadow: rgba(0, 0, 0, 0.0470588) 0px 1px 1px inset; color: rgb(88, 102, 110); font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, 微软雅黑, 黑体, sans-serif; font-size: 14px; line-height: 20px;"><pre class="prettyprint" style="box-sizing: border-box; overflow: auto; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 13px; padding: 9.5px; margin-top: 0px; margin-bottom: 10px; line-height: 1.42857143; color: rgb(51, 51, 51); word-break: break-all; word-wrap: break-word; background-color: rgb(237, 241, 242); border: 1px solid rgb(222, 229, 231); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px;"><pre name="code" class="cpp">
#include<iostream>
#include<vector>
#include<queue>
#include<list>
#include<cmath>
#include<climits>
#include<cstdio>
using namespace std;
int n,s,t,maxn,cmin=INT_MAX/100,cmin2=INT_MAX/100,cmin3=INT_MAX/100,num,num2,num3;
int c[10000000];
int sum=0;
int fa[10000000];
bool flag[100]={0};
int map[100][100];
void dfs(int x,int xu,int y)
{  if(x==t)
   {
   if(y<cmin)
      {cmin3=cmin2;
        num3=num2;
        cmin2=cmin;
        num2=num;
        cmin=y;
        num=xu;
      return;
	  }
	  if(y<cmin2)
	  {cmin3=cmin2;
        num3=num2;
        cmin2=y;
        num2=xu;
        return;
	  }
	  if(y<cmin3)
	   {cmin3=y;
	    num3=xu;
	   }
    return;
    }
   for(int i=1;i<=n;i++)
   if(flag[i]==0&&map[x][i]!=maxn)
    {flag[i]=1;
     sum++;fa[sum]=xu;c[sum]=i;
      dfs(i,sum,y+map[x][i]);
      flag[i]=0;
    } 
}

int main()
{cin>>n>>s>>t>>maxn;
 for(int i=1;i<=n;i++)
  for(int j=1;j<=n;j++)
    scanf("%d",&map[i][j]);
    c[0]=s;flag[s]=1;
dfs(s,0,0);

vector<int>::reverse_iterator i; 
vector<int> ans;
int u=num;
   while(u!=0)
    {ans.push_back(c[u]);
      u=fa[u];
    }
    ans.push_back(s);
    cout<<cmin<<' ';
  for (i = ans.rbegin(); i != ans.rend();++i) 
    cout << *i<<' '; 
    cout<<endl;
    ans.clear();
    u=num2;
   while(u!=0)
    {ans.push_back(c[u]);
      u=fa[u];
    }
    ans.push_back(s);
    cout<<cmin2<<' ';
  for (i = ans.rbegin(); i != ans.rend();++i) 
    cout << *i<<' '; 
    cout<<endl;
    ans.clear(); u=num3;
   while(u!=0)
    {ans.push_back(c[u]);
      u=fa[u];
    }
    ans.push_back(s);
    cout<<cmin3<<' ';
  for (i = ans.rbegin(); i != ans.rend();++i) 
    cout << *i<<' '; 
    cout<<endl;
	return 0;
}

本来想用多次spfa后来发现很麻烦。。就写了搜索。但是这里最好用深搜因为会节省记录路径的空间
 
     

题目描述  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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值