【洛谷P4568】 [JLOI2011]飞行路线

飞行路线

题目链接

今天上午模拟考试考了原题,然而数组开小了,爆了4个点。

据王♂强dalao说这是一道分层图SPFA的裸题

dis[i][j]表示到点i用k个医疗包的最小消耗,dis[u][j]+e[i].w更新dis[v][j],

dis[u][j]更新dis[v][j+1]

然而它卡SPFA,会TLE几个点

于是就有了堆优化SPFA。。

#include<cstring>
#include<cstdio>
#include<queue>
#define INF 0x3f3f3f3f
#define N 10010
int n,m,k,s,t,ans=INF;
int dis[N][12];
struct HA{
    int pos,cost,times;
};
struct cmp{
    bool operator()(HA x,HA y){
        return x.cost==y.cost?x.times>y.times:x.cost>y.cost;
    }
};
std::priority_queue< HA, std::vector<HA>, cmp > q;
bool vis[N][12];
int Head[N],num;
struct NODE{
    int to,w,next;
} e[100010];
const int ch_top=4e7+3;
char ch[ch_top],*now_r=ch-1,*now_w=ch-1;
inline int read(){
    while(*++now_r<'0');
    register int x=*now_r-'0';
    while(*++now_r>='0')x=x*10+*now_r-'0';
    return x;
}
inline void write(int x){
    static char st[20];static int top;
    while(st[++top]='0'+x%10,x/=10);
    while(*++now_w=st[top],--top);
    *++now_w='\n';
}
void SPFA(){
    memset(dis,0x3f,sizeof(dis));
    for(int i=0;i<=k;i++){
        dis[s][i]=0;
        q.push((HA){s,0,i});
    }
    while(!q.empty()){
        int u=q.top().pos,f=q.top().times;
        q.pop();
        vis[u][f]=0;
        for(int i=Head[u];i;i=e[i].next){
            int v=e[i].to;
            if(dis[v][f]>dis[u][f]+e[i].w){
                dis[v][f]=dis[u][f]+e[i].w;
                if(!vis[v][f]){
                    vis[v][f]=1;
                    q.push(HA{v,dis[v][f],f});
                }
            }
            if(f<k&&dis[v][f+1]>dis[u][f]){
                dis[v][f+1]=dis[u][f];
                if(!vis[v][f+1]){
                    vis[v][f+1]=1;
                    q.push(HA{v,dis[v][f+1],f+1});
                }
            }
        }
    }
}
int main()
{    
    fread(ch,1,ch_top,stdin);
    n=read(); m=read(); k=read();
    s=read(); t=read();
    int x,y,w;
    for(int i=1;i<=m;i++){
        x=read(); y=read(); w=read();
        e[++num].to=y;
        e[num].w=w;
        e[num].next=Head[x];
        Head[x]=num;
        e[++num].to=x;
        e[num].w=w;
        e[num].next=Head[y];
        Head[y]=num;
    }
    SPFA();
    write(dis[t][k]);
    fwrite(ch,1,now_w-ch,stdout);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yjkhhh/p/9404075.html
今日推荐