显然分层图裸题,做这题纯粹是为了填坑,不解释。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define dbg(x) cerr << #x << " = " << x <<endl 8 using namespace std; 9 typedef long long ll; 10 typedef double db; 11 typedef pair<int,int> pii; 12 template<typename T>inline T _min(T A,T B){return A<B?A:B;} 13 template<typename T>inline T _max(T A,T B){return A>B?A:B;} 14 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;} 15 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;} 16 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;} 17 template<typename T>inline T read(T&x){ 18 x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1; 19 while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x; 20 } 21 const int N=10000+2,M=50000+2,INF=0x3f3f3f3f; 22 struct thxorz{ 23 int to,nxt,w; 24 }G[M*2*22]; 25 int Head[N*11],tot; 26 int n,m,k,s,t,ans=INF; 27 inline void Addedge(int x,int y,int z){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;} 28 int dis[N*11]; 29 priority_queue<pii,vector<pii>,greater<pii> > q; 30 #define y G[j].to 31 inline void dij(){ 32 memset(dis,0x3f,sizeof dis);q.push(make_pair(dis[k*n+s]=0,k*n+s)); 33 while(!q.empty()){ 34 int x=q.top().second,d=q.top().first;q.pop(); 35 if(d^dis[x])continue; 36 for(register int j=Head[x];j;j=G[j].nxt)if(MIN(dis[y],d+G[j].w))q.push(make_pair(dis[y],y)); 37 } 38 } 39 #undef y 40 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout); 41 read(n),read(m),read(k),read(s),read(t);++s,++t; 42 for(register int i=1,x,y,z;i<=m;++i){ 43 read(x),read(y),read(z);++x,++y; 44 for(register int j=0,l=0;j<=k;++j,l+=n)Addedge(l+x,l+y,z),Addedge(l+y,l+x,z); 45 for(register int j=0,l=0;j<k;++j,l+=n)Addedge(l+n+x,l+y,0),Addedge(l+n+y,l+x,0); 46 } 47 dij(); 48 for(register int i=0;i<=k;++i)MIN(ans,dis[i*n+t]); 49 return printf("%d ",ans),0; 50 }
注:其实这么多边没必要建出来,跑dij的时候直接按原图的边,做免费和不免费两种转移就行了。