题意:
给你边权,起点和终点,有k次机会把某条路变为0,问你最短路是多长。
思路:
分层最短路模板题。题目有点坑(卡掉了SPFA,只能用dijkstra跑的算法)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 7 const int MAXN=1e3,MAXM=5e3,MAXK=1000,INF=~0U>>1; 8 int N,M,K; 9 int S,T; 10 11 struct E{int to,next,value;} e[4*MAXM*(MAXK+1)+MAXK+1];int ecnt,G[MAXN*(MAXK+1)+1]; 12 void addEdge(int u,int v,int w){e[++ecnt]={v,G[u],w};G[u]=ecnt;} 13 14 void readInt(int & x) 15 { 16 x=0; 17 bool flag=false; 18 char c; 19 do c=getchar(); while(c!='-'&&(c<'0'||c>'9')); 20 if(c=='-') flag=true; 21 else x+=c-'0'; 22 c=getchar(); 23 while(c>='0'&&c<='9') 24 { 25 x*=10; 26 x+=c-'0'; 27 c=getchar(); 28 } 29 } 30 31 inline void read() 32 { 33 int i,j; 34 readInt(N);readInt(M); 35 readInt(S);readInt(T);readInt(K); 36 for(i=1;i<=M;i++) 37 { 38 int u,v,w; 39 readInt(u);readInt(v);readInt(w); 40 for(j=0;j<=K;j++) 41 { 42 addEdge(u+N*j,v+N*j,w); 43 addEdge(v+N*j,u+N*j,w); 44 if(j!=K) 45 { 46 addEdge(u+N*j,v+N*(j+1),0); 47 addEdge(v+N*j,u+N*(j+1),0); 48 } 49 } 50 } 51 } 52 53 struct HN{int id,v;bool operator<(const HN & ot)const{return v>ot.v;}}; 54 55 priority_queue<HN> heap; 56 57 bool inS[MAXN*(MAXK+1)+1]; 58 int dis[MAXN*(MAXK+1)+1]; 59 60 void dijkstra(int v0) 61 { 62 int i; 63 for(i=1;i<=N*(K+1);i++) dis[i]=INF; 64 memset(inS,false,sizeof(inS)); 65 dis[v0]=0; 66 heap.push((HN){v0,0}); 67 while(!heap.empty()) 68 { 69 int u=heap.top().id;heap.pop(); 70 if(inS[u]) continue; 71 inS[u]=true; 72 for(i=G[u];i;i=e[i].next) 73 { 74 int v=e[i].to; 75 if(!inS[v]) 76 if(dis[v]>dis[u]+e[i].value) 77 { 78 dis[v]=dis[u]+e[i].value; 79 heap.push((HN){v,dis[v]}); 80 } 81 } 82 } 83 } 84 85 int main() 86 { 87 //freopen("Motor.in","r",stdin); 88 //freopen("Motor.out","w",stdout); 89 int i; 90 read(); 91 dijkstra(S); 92 int ans=INF; 93 for(i=0;i<=K;i++) ans=min(ans,dis[T+N*i]); 94 printf("%d",ans); 95 return 0; 96 }