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; }