题目链接:https://ac.nowcoder.com/acm/contest/884/J
题目大意:
给出一个无向图,每条边对应一个花费,有k次机会能让一条边的花费为0,让求s到t的最短路。
解题报告:
分层图最短路,就当是模板吧,下面给出两份AC代码。
建图大概长这样
AC代码:
1.直接暴力建图,花费空间和时间较大。
语言:C++ 代码长度:2264 运行时间: 269 ms 占用内存:121836K
1 #include2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar('\n') 5 #define pb push_back 6 #define fi first 7 #define se second 8 #define fre1 freopen("1.txt","r",stdin) 9 #define fre2 freopen("3.txt","w",stdout) 10 #define bug cout<<"*******************"< #define debug(args...) cout<<#args<<"->"<11 12 using namespace std; 13 template 14 void read(T &res) { 15 bool flag=false;char ch; 16 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 17 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 18 flag&&(res=-res); 19 } 20 template 21 void write(T x) { 22 if(x<0) putchar('-'),x=-x; 23 if(x>9) write(x/10); 24 putchar(x%10+'0'); 25 } 26 typedef long long ll; 27 typedef unsigned long long ull; 28 const int maxn=9003010; ///n*(k+1) 29 const int maxm=505; 30 const int mod=1e9+7; 31 const int inv2=500000004; 32 const int inf=0x3f3f3f3f; 33 const ll INF=0x3f3f3f3f3f3f3f3f; 34 const int N=32; 35 struct node { 36 int v,net,w; 37 }e[maxn<<2]; ///分层图层和层之前也有边,边*4 38 int head[maxn],dis[maxn],vis[maxn]; 39 #define pr pair 40 int S,T,cnt; 41 void add(int u,int v,int w) { 42 e[++cnt]={v,head[u],w}; 43 head[u]=cnt; 44 } 45 void dijstra() { 46 priority_queue ,greater >que; 47 memset(dis,inf,sizeof(dis)); 48 que.push(make_pair(0,S)); 49 dis[S]=0; 50 while(!que.empty()) { 51 int u=que.top().se;que.pop(); 52 if(vis[u]) continue; 53 vis[u]=true; 54 for(int i=head[u];~i;i=e[i].net) { 55 int v=e[i].v,w=e[i].w; 56 if(!vis[v]&&dis[v]>dis[u]+w) { 57 dis[v]=dis[u]+w; 58 que.push(make_pair(dis[v],v)); 59 } 60 } 61 } 62 } 63 int main() 64 { 65 // #define local 66 #ifdef local 67 fre1; 68 fre2; 69 #endif // local 70 int n,m,k; 71 memset(head,-1,sizeof(head)); 72 read(n),read(m),read(S),read(T),read(k); 73 for(int i=1;i<=m;i++) { 74 int u,v,w; 75 read(u),read(v),read(w); 76 for(int j=0;j<=k;j++) { 77 add(u+j*n,v+j*n,w); 78 add(v+j*n,u+j*n,w); 79 if(j!=k) { 80 add(u+j*n,v+(j+1)*n,0); 81 add(v+j*n,u+(j+1)*n,0); 82 } 83 } 84 } 85 dijstra(); 86 int minn=inf; 87 for(int i=0;i<=k;i++) 88 minn=min(minn,dis[T+i*n]); 89 write(minn);pn; 90 return 0; 91 }
2.用数组标记状态,省空间也省时间
语言:C++ 代码长度:2374 运行时间: 214 ms 占用内存:43628K
1 #include2 #define numm ch-48 3 #define pd putchar(' ') 4 #define pn putchar('\n') 5 #define pb push_back 6 #define fi first 7 #define se second 8 #define fre1 freopen("1.txt","r",stdin) 9 #define fre2 freopen("3.txt","w",stdout) 10 #define bug cout<<"*******************"< #define debug(args...) cout<<#args<<"->"<11 12 using namespace std; 13 template 14 void read(T &res) { 15 bool flag=false;char ch; 16 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 17 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 18 flag&&(res=-res); 19 } 20 template 21 void write(T x) { 22 if(x<0) putchar('-'),x=-x; 23 if(x>9) write(x/10); 24 putchar(x%10+'0'); 25 } 26 typedef long long ll; 27 typedef unsigned long long ull; 28 const int maxn=3010; ///n*(k+1) 29 const int maxm=505; 30 const int mod=1e9+7; 31 const int inv2=500000004; 32 const int inf=0x3f3f3f3f; 33 const ll INF=0x3f3f3f3f3f3f3f3f; 34 const int N=32; 35 struct node { 36 int v,net,w; 37 }e[maxn<<1]; ///分层图层和层之前也有边,边*4 38 int head[maxn]; 39 int dis[maxn][maxn],vis[maxn][maxn]; 40 ///dis[i][k],用掉k次机会到达i点的花费 41 #define pr pair 42 int S,T,cnt,n,k; 43 void add(int u,int v,int w) { 44 e[++cnt]={v,head[u],w}; 45 head[u]=cnt; 46 } 47 void dijstra() { 48 priority_queue ,greater >que; 49 memset(dis,inf,sizeof(dis)); 50 que.push(make_pair(0,S-1)); 51 dis[S][0]=0; 52 while(!que.empty()) { 53 int u=que.top().se;que.pop(); 54 int c=u/n;u=u%n+1; 55 if(vis[u][c]) continue; 56 vis[u][c]=true; 57 for(int i=head[u];~i;i=e[i].net) { 58 int v=e[i].v,w=e[i].w; 59 if(!vis[v][c]&&dis[v][c]>dis[u][c]+w) { ///先不用机会到达下一顶点 60 dis[v][c]=dis[u][c]+w; 61 que.push(make_pair(dis[v][c],v-1+c*n)); 62 } 63 if(c!=k&&!vis[v][c+1]&&dis[v][c+1]>dis[u][c]) { 64 dis[v][c+1]=dis[u][c]; 65 que.push(make_pair(dis[v][c+1],v-1+(c+1)*n)); 66 } 67 } 68 } 69 } 70 int main() 71 { 72 // #define local 73 #ifdef local 74 fre1; 75 fre2; 76 #endif // local 77 int m; 78 memset(head,-1,sizeof(head)); 79 read(n),read(m),read(S),read(T),read(k); 80 for(int i=1;i<=m;i++) { 81 int u,v,w; 82 read(u),read(v),read(w); 83 add(u,v,w); 84 add(v,u,w); 85 } 86 dijstra(); 87 int minn=inf; 88 for(int i=0;i<=k;i++) 89 minn=min(minn,dis[T][i]); 90 write(minn);pn; 91 return 0; 92 }