首页 > 其他 > 详细

$Luogu$ $P4568$ $[JLOI2011]$ 飞行路线

时间:2019-11-12 23:54:16      阅读:117      评论:0      收藏:0      [点我收藏+]

链接

背景

\(CCF\) \(NOI\) \(2011\) 吉林省代表队选拔, \(Luogu\) \(P4568/BZOJ2763\)

题意

给定 \(n\) 个点, \(m\) 条边的两个端点 \(x,y\) ,规定一条路径上最多可以使得 \(k\) 条边变成 \(0\) 。求 \(s\)\(t\) 的最短路径长度。

解法

分层图最短路模板。
由于可以免费 \(k\) 次,建 \(k\) 层图(假定变成 \(0\) 的边数越多图越高)即可。
注意每条边在每一层上连一遍,然后 \(x\) 向高一层的 \(y\)\(0\) 边, \(y\) 向高一层的 \(x\)\(0\) 边。
\(s\) 点开始 \(dijkstra\) ,答案是所有层上第 \(t\) 个点的最短路的最小值。

代码

\(View\) \(Code\)

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int ret=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ret=(ret<<1)+(ret<<3)+ch-'0';
        ch=getchar();
    }
    return ret*f;
}
int n,m,k,s,t,u,v,w;
int dis[200005],ans=2e9;
int num,head[200005];
bool vis[200005];
struct edge
{
    int ver,nxt,w;
}e[3000005];
inline void adde(int u,int v,int w)
{
    e[++num].ver=v;
    e[num].w=w;
    e[num].nxt=head[u];
    head[u]=num;
}
void dijkstra(int s)
{
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    priority_queue<pair<int,int> > q;
    dis[s]=0;
    q.push(make_pair(0,s));
    while(!q.empty())
    {
        int x=q.top().second;
        q.pop();
        if(vis[x])
            continue;
        vis[x]=1;
        for(register int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].ver,w=e[i].w;
            if(dis[x]+w<dis[y])
            {
                dis[y]=dis[x]+w;
                q.push(make_pair(-dis[y],y));
            }
        }
    }
}
int main()
{
    n=read();
    m=read();
    k=read();
    s=read()+1;
    t=read()+1;
    for(register int i=1;i<=m;i++)
    {
        u=read()+1;
        v=read()+1;
        w=read();
        adde(u,v,w);
        adde(v,u,w);
        for(register int j=1;j<=k;j++)
        {
            adde(u+(j-1)*n,v+j*n,0);
            adde(v+(j-1)*n,u+j*n,0);
            adde(u+j*n,v+j*n,w);
            adde(v+j*n,u+j*n,w);
        }
    }
    dijkstra(s);
    for(register int i=0;i<=k;i++)
        ans=min(ans,dis[t+i*n]);
    printf("%d\n",ans);
    return 0;
}

$Luogu$ $P4568$ $[JLOI2011]$ 飞行路线

原文:https://www.cnblogs.com/Peter0701/p/11846127.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!