POJ3255 Roadblocks dij求次短路 [模板]

对于poj3255。

第一次接触次短路。

比较棘手。

后来是参考着别人的代码ac的。

哎。

下面是模板。

转载自http://noname01.pas.blog.163.com/blog/static/124363634201071491853102/

dijkstra变形求次短路  



2010-08-14 09:19:20|  分类: 树和图 |  标签:次短路  dijkstra   |字号 订阅
在dijkstra基础上稍加变形即可求出次短路
(这里的次短路指长度大于等于最短路的路径中长度最小的一条,可以走到走过的点)
对每个节点v,记录源点到v的最短路dis1[v]和次短路dis2[v]。
用flag1[v]和flag2[v]分别标记每个节点的最短路和次短路是否求出,初始化为0。
初始化最短路dis1[v]和次短路dis2[v],没有则为maxint。
每次选取未标记的最短路和次短路中距离最近的节点,进行标记,
并用此值对其他所有节点进行松弛操作,更新其最优值和次优值。
若能更新最优值,则把次优值赋值为旧的最优值,用新的最优值覆盖元最优值。若能更新次优值则直接更新。
这样操作完毕,就可以求出源点到其他节点的最短路和次短路。


程序如下:


#include<iostream>
#define maxint 2139062143
using namespace std;
int g[101][101],flag1[101],flag2[101],dis1[101],dis2[101],n,m,v0,v1;
void init(){
int i,x,y,k;
freopen("cdl.in","r",stdin);
freopen("cdl.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&v0,&v1);
memset(g,127,sizeof(g));
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&k);
g[x][y]=k;
g[y][x]=k;
}
memset(flag1,0,sizeof(flag1));
memset(flag2,0,sizeof(flag2));
}
void dijkstra(){
int Min,i,u,p;
for(i=1;i<=n;i++){
dis1[i]=g[v0][i];
dis2[i]=maxint;
}
u=1;
flag1[v0]=1;
dis1[v0]=0;
while(u>0){
u=-1;
Min=maxint;
for(i=1;i<=n;i++)
if(Min>dis1[i]&&flag1[i]==0){
Min=dis1[i];
u=i;
}
p=1;
for(i=1;i<=n;i++)
if(Min>dis2[i]&&flag2[i]==0){
Min=dis2[i];
u=i;
p=2;
}
if(u>0){
if(p==1)
flag1[u]=1;
else
flag2[u]=1;
for(i=1;i<=n;i++){
if(dis1[i]-Min>g[u][i]){
dis2[i]=dis1[i];
dis1[i]=Min+g[u][i];
}
else if(dis2[i]-Min>g[u][i])
dis2[i]=Min+g[u][i];
}
}
}
}
void solve(){
dijkstra();
printf("%d\n",dis2[v1]);
}
int main(){
init();
solve();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值