https://nanti.jisuanke.com/t/31001
题意 可以把k条边的权值变为0,求s到t的最短路
解析 分层最短路 我们建立k+1层图 层与层之间边权为0,i 向 i+1层转移,代表用了一条免费边。
#include <bits/stdc++.h> #define pb push_back #define mp make_pair #define fi first #define se second #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) #define huan printf(" "); #define debug(a,b) cout<<a<<" "<<b<<" "; using namespace std; const int maxn=3e6+10,inf=0x3f3f3f3f; typedef long long ll; typedef pair<int,int> pii; int n,m,k,st,ed,cnt,head[maxn],vis[maxn]; ll dis[maxn]; struct node { ll from,to,val,next; } edge[maxn<<1]; struct element { ll val,now; }; bool operator < (element a,element b) { if(a.val==b.val) return a.now<b.now; return a.val>b.val; } void dijikstra(int s,int e) { priority_queue<element>q; memset(dis,0x3f,sizeof(dis)); dis[s]=0; q.push(element{0,s}); while(!q.empty()) { element u=q.top(); q.pop(); if(vis[u.now]) continue; vis[u.now]=1; for(int i=head[u.now]; i!=-1; i=edge[i].next) { int to=edge[i].to; if(dis[u.now]+edge[i].val<dis[to]) { dis[to]=dis[u.now]+edge[i].val; q.push(element{dis[to],to}); } } } ll ans=1e18; for(int i=0; i<=k; i++) { if(ans>dis[e+i*n]) ans=dis[e+i*n]; } printf("%lld ",ans); } void init() { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); cnt=1; } void edgeadd(ll from,ll to,ll val) { edge[cnt].from=from; edge[cnt].to=to; edge[cnt].val=val; edge[cnt].next=head[from]; head[from]=cnt++; } int main() { int t; scanf("%d",&t); while(t--) { init(); scanf("%d%d%d",&n,&m,&k); st=1,ed=n; for(int i=1; i<=m; i++) { ll x,y,z; scanf("%lld%lld%lld",&x,&y,&z); for(int i=0; i<=k; i++) //分为k+1层图, { edgeadd(x+i*n,y+i*n,z); //每层图之间建边 if(i!=k) { edgeadd(x+i*n,y+(i+1)*n,0);//第层i向i+1层图建边 边权为0; } } } dijikstra(st,ed); } }
BZOJ 2763
dp思想
/************************************************************** Problem: 2763 User: 1071532391 Language: C++ Result: Accepted Time:7452 ms Memory:6972 kb ****************************************************************/ #include <bits/stdc++.h> #define pb push_back #define mp make_pair #define fi first #define se second #define all(a) (a).begin(), (a).end() #define fillchar(a, x) memset(a, x, sizeof(a)) #define huan printf(" "); #define debug(a,b) cout<<a<<" "<<b<<" "; using namespace std; const int maxn=2e4+10,inf=0x3f3f3f3f; typedef long long ll; typedef pair<int,int> pii; struct edge { int u,v,w,next; }e[maxn*10]; struct node { int x,y; }; int cnt,dis[maxn][15],head[maxn],vis[maxn][15]; int n,m,k,s,t; void init() { cnt=0; fillchar(head,-1); fillchar(vis,0); } void addedge(int u,int v,int w) { e[++cnt].next=head[u]; e[cnt].u=u; e[cnt].v=v; e[cnt].w=w; head[u]=cnt; } void spfa() { fillchar(dis,0x3f); queue<node> q; q.push(node{s,k}); dis[s][k]=0; while(!q.empty()) { int u=q.front().x; int t=q.front().y; q.pop(); vis[u][t]=0; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v,w=e[i].w; if(dis[v][t]>dis[u][t]+w) { dis[v][t]=dis[u][t]+w; if(!vis[v][t]) { vis[v][t]=1; q.push(node{v,t}); } } if(t>0&&dis[v][t-1]>dis[u][t]) { dis[v][t-1]=dis[u][t]; if(!vis[v][t-1]) { vis[v][t-1]=1; q.push(node{v,t-1}); } } } } int ans=1e9; for(int i=0;i<=k;i++) { //cout<<dis[i][0]<<" "<<i<<endl; ans=min(ans,dis[t][i]); } printf("%d ",ans); } int main() { init(); scanf("%d%d%d%d%d",&n,&m,&k,&s,&t); for(int i=0;i<m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); addedge(v,u,w); } spfa(); return 0; }