https://nanti.jisuanke.com/t/31001
题意:
有n个城市,m条有向路,最多选取k条路的权值为0,求1到n的最短路。
思路:
我们可以当每个点分成k 层,同一层的点的权值为w,到下一层的权值为0,这样建图,就能保证最短k条边的权值为0,然后跑最短路。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=2e6+10;
const int maxm=5e6+10;
const ll inf=1e18;
struct node
{
int u,v,w,next;
}edge[maxm];
int head[maxn];
int n,m,k;
int cnt;
struct Node
{
int id;
ll cost;
}dis[maxn];
bool operator<(Node a,Node b)
{
return a.cost>b.cost;
}
void init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)
{
for(int i=0;i<=k;i++)
{
edge[cnt].u=u+i*n;
edge[cnt].v=v+i*n;
edge[cnt].w=w;
edge[cnt].next=head[u+i*n];
head[u+i*n]=cnt++;
}
for(int i=0;i<k;i++)
{
edge[cnt].u=u+i*n;
edge[cnt].v=v+(i+1)*n;
edge[cnt].w=0;
edge[cnt].next=head[u+i*n];
head[u+i*n]=cnt++;
}
}
bool vis[maxn];
void dij()
{
for(int i=1;i<=n*k+n;i++)
dis[i].id=i,dis[i].cost=inf;
dis[1].cost=0;
priority_queue<Node>q;
q.push(dis[1]);
while(!q.empty())
{
Node u=q.top();
q.pop();
for(int i=head[u.id];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
int w=edge[i].w;
if(dis[v].cost>dis[u.id].cost+w)
dis[v].cost=dis[u.id].cost+w,q.push(dis[v]);
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
init();
int u,v,w;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
dij();
printf("%lld\n",dis[n*k+n].cost);
}
return 0;
}