我们可能遇到这样的图论模型:在一个正常的图上可以进行 k 次决策,对于每次决策,不影响图的结构,只影响目前的状态或代价。同时这个图论模型和经典的最短路有关,这样我们可以考虑运用分层图最短路。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define ll long long using namespace std; const int maxn=10009; const int maxm=50009; int n,m,k,s,t; struct node{ int v,nxt,w; }e[maxm<<1]; int head[maxn],cnt; inline void add(int u,int v,int w){ e[++cnt].v=v;e[cnt].nxt=head[u];e[cnt].w=w;head[u]=cnt; } int dis[maxn][11]; bool v[maxn][11]; struct poi{ int x,w,cnt;//cnt使用次数 poi(){} poi(int xx,int ww,int cntt){ x=xx;w=ww;cnt=cntt; } bool operator <(const poi &a)const{ return w>a.w; } }; priority_queue<poi> q; void dij(int s){ memset(dis,0x7f,sizeof(dis)); dis[s][0]=0; q.push(poi(s,0,0)); while(!q.empty()){ poi p=q.top();q.pop(); int x=p.x,cnt=p.cnt; if(v[x][cnt])continue; v[x][cnt]=1; for(int i=head[x];i;i=e[i].nxt){ int y=e[i].v,w=e[i].w; if(cnt<k && dis[y][cnt+1]>dis[x][cnt]){ dis[y][cnt+1]=dis[x][cnt]; q.push(poi(y,dis[y][cnt+1],cnt+1)); } if(dis[y][cnt]>dis[x][cnt]+w){ dis[y][cnt]=dis[x][cnt]+w; q.push(poi(y,dis[y][cnt],cnt)); } } } } int main(){ scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t);s++,t++; for(int i=1,u,v,w;i<=m;i++){ scanf("%d%d%d",&u,&v,&w);v++,u++; add(u,v,w);add(v,u,w); } dij(s);int ans=2000000000; for(int i=0;i<=k;i++) ans=min(ans,dis[t][i]); printf("%d",ans); // for(int j=1;j<=n;j++) // for(int i=0;i<=k;i++)printf("%d ",dis[j][i]); }