题目链接:​​https://nanti.jisuanke.com/t/31001​

计蒜客 31001 - Magical Girl Haze - [最短路][2018ICPC南京网络预赛L题]_计蒜客

 

题意:

一带权有向图,有 n 个节点编号1~n,m条有向边,现在一人从节点 1 出发,他有最多 k 次机会施展魔法使得某一条边的权变成 0,问他走到节点 n 的最小权值为多少。

 

题解:

将dist数组和vis数组都扩展一维:

dist[c][i]代表:已经使用了 c 次变0魔法后,走到节点 i 的最短距离;

vis[c][i]代表:已经使用了 c 次变0魔法后,走到节点 i 的最短距离,这个最短距离是否已经被准确计算完毕。

然后就是稍微改动一下原来的优先队列优化Dijkstra即可。

 

AC代码:



#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn=1e5+10;
const int maxm=2e5+10;
const int maxk=13;
const ll INF=0x3f3f3f3f3f3f3f3f;

int n,m,k;

struct Edge{
int u,v;
ll w;
Edge(int u=0,int v=0,ll w=0){this->u=u,this->v=v,this->w=w;}
};
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int u,int v,ll w)
{
E.push_back(Edge(u,v,w));
G[u].push_back(E.size()-1);
}

struct Qnode{
int vertex;
ll dist;
int cnt;
Qnode(int v=0,ll d=0,int c=0){this->vertex=v,this->dist=d,this->cnt=c;}
bool operator <(const Qnode &oth)const{
return dist>oth.dist;
}
//优先队列默认是降序排列,如果本节点小于另一个节点的意义是 本节点dist < 另一个节点dist,
//则优先队列的队首放的就是最大的节点,就是dist最大的节点,显然我们要的是相反的情况,
//所以设置本节点小于另一个节点的意义是 本节点dist > 另一个节点dist 即可。
};

ll dist[maxk][maxn];
bool vis[maxk][maxn];
void dijkstra(int s)
{
for(int i=1;i<=n;i++)
{
for(int c=0;c<=k;c++)
{
dist[c][i]=((i==s)?0:INF);
vis[c][i]=0;
}
}

priority_queue<Qnode> Q;
Q.push(Qnode(s,0,0));
while(!Q.empty())
{
int u=Q.top().vertex, c=Q.top().cnt; Q.pop();
if(vis[c][u]) continue;
vis[c][u]=1;
for(int i=0;i<G[u].size();i++)
{
Edge &e=E[G[u][i]]; int v=e.v;
if(!vis[c][v] && dist[c][v]>dist[c][u]+e.w)
{
dist[c][v]=dist[c][u]+e.w;
Q.push(Qnode(v,dist[c][v],c));
}
if(c+1<=k && !vis[c+1][v] && dist[c+1][v]>dist[c][u])
{
dist[c+1][v]=dist[c][u];
Q.push(Qnode(v,dist[c+1][v],c+1));
}
}
}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
init(1,n);
for(int i=1;i<=m;i++)
{
int u,v; ll w;
scanf("%d%d%lld",&u,&v,&w);
addedge(u,v,w);
}
dijkstra(1);
ll ans=INF;
for(int c=0;c<=k;c++) ans=min(ans,dist[c][n]);
printf("%lld\n",ans);
}
}


 

 ​