【hdu6181】Two Paths(次短路----每条边经过不止一次)

题目:我是超链接

题意:求1-n的次短路

题解:
A∗算法可以用来求第k短路,当然也可以用来求次短路。

此题也可以直接用求次短路的方法(在Dijkstra上进行少许修改)解决。到某个顶点v的次短路要么是到其他某个顶点u的最短路再加上u→v的边,要么是到u的次短路再加上u→v的边。对于每个顶点,我们记录的不仅仅是最短距离,还有次短距离。在跑Dijkstra时,不断更新这两个距离即可。 

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#define M 200005  
#define N 100005 
#define LL long long
using namespace std;
const LL INF=1e18;
LL dis[N],dis2[N];//次短距离
int point[N],tot,nxt[M],v[M],c[M];
void addedge(int x,int y,int t){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=t;}
struct hh{LL f;int i;bool operator <(const hh &a)const{return a.f<f;}};  
void Dij(int t,int s)//点的编号从1开始
{
	for(int i=0;i<=t;i++) dis[i]=INF,dis2[i]=INF;
    priority_queue<hh> q;
    dis[s]=0;
    q.push((hh){0,s});
    while(!q.empty())
    {
        hh now=q.top(); q.pop();
        int u=now.i;
        LL d=now.f;
        if(dis2[u]<d) continue;
        for(int i=point[u];i;i=nxt[i])
        {
            LL d2=d+c[i];
            if(dis[v[i]]>d2)
            {
            	dis2[v[i]]=dis[v[i]];
            	dis[v[i]]=d2;
                q.push((hh){dis[v[i]],v[i]});
            }
            else
            if(dis2[v[i]]>d2)
            {
                dis2[v[i]]=d2;
                q.push((hh){dis2[v[i]],v[i]});
            }
        }
    }
}
int main()
{
    int T,u,v,w,n,m,s,t;
    scanf("%d",&T);
    while(T--)
    {
    tot=0; memset(point,0,sizeof(point));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        addedge(u,v,w);addedge(v,u,w);
    }
    Dij(n,1);
    printf("%lld\n",dis2[n]);	
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值