P1948 [USACO08JAN]电话线Telephone Lines

P1948 [USACO08JAN]电话线Telephone Lines

最短路spfa

暴力分层spfa。没了。(luogu数据太水,正解二分+spfa都没用上)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cctype>
using namespace std;
template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
template <typename T> inline void read(T &x){
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
struct data{int u,k;};
queue <data> h;
int n,m,tk,ans=1e9,d[1002][1002]; bool vis[1002][1002];
int cnt,hd[1002],nxt[20002],ed[1002],poi[20002],val[20002];

inline void add(int &x,int &y,int &v){
    nxt[ed[x]]=++cnt; hd[x]= hd[x] ? hd[x]:cnt;
    ed[x]=cnt; poi[cnt]=y; val[cnt]=v;
}
int main(){
    read(n); read(m); read(tk); int q1,q2,q3;
    for(int i=1;i<=m;++i) read(q1),read(q2),read(q3),add(q1,q2,q3),add(q2,q1,q3);
    memset(d,127,sizeof(d)); 
    h.push((data){1,tk}); d[1][tk]=0; vis[1][tk]=1;
    while(!h.empty()){
        data x=h.front(); h.pop(); vis[x.u][x.k]=0;
        for(int i=hd[x.u];i;i=nxt[i]){
            if(d[poi[i]][x.k]>max(d[x.u][x.k],val[i])){ //付费
                d[poi[i]][x.k]=max(d[x.u][x.k],val[i]);
                if(!vis[poi[i]][x.k]) h.push((data){poi[i],x.k}),vis[poi[i]][x.k]=1;
            }
            if(x.k&&d[poi[i]][x.k-1]>d[x.u][x.k]){ //不付费
                d[poi[i]][x.k-1]=d[x.u][x.k];
                if(!vis[poi[i]][x.k-1]) h.push((data){poi[i],x.k-1}),vis[poi[i]][x.k-1]=1;
            }
        }
    }
    for(int i=0;i<=tk;++i) ans=min(ans,d[n][i]);
    if(ans==1e9) printf("-1");
    else printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/kafuuchino/p/9690770.html