分层图是个十分有用的东西。
用于处理图上k个边权特殊化的情况。
比如可以让k条边边权为0或除以二。而且一般k很小。
我们可以把图分成k+1层。
先把原图复制k份。
然后连接两两图之间用特殊边权连接。
比如这一题,,我们让所有存在的边,两两层之间边权为0,代表执行一次边权为0的操作。
因为最多k层,所以最多执行k次操作,注意:这里连边要连单向边,即执行操作后不能回去。
建完图后dij一跑就结束了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int M = 2e6+7;
int head[M],cnt;
struct EDGE{int to,nxt,val;}ee[M*2];
void add(int x,int y,int z){ee[++cnt].nxt=head[x],ee[cnt].to=y,ee[cnt].val=z,head[x]=cnt;}
int n,m,k,st,ed;
priority_queue<pii,vector<pii>,greater<pii> >q;
int d[M],vs[M];
void dij()
{
memset(d,0x3f,sizeof(d));
memset(vs,0,sizeof(vs));
d[st]=0;
q.push({0,st});
while(q.size())
{
int u=q.top().second;q.pop();
if(vs[u])continue;//第一次取的一定是最优情况
vs[u]=1;
for(int i=head