2018南京網路賽L題 Magical Girl Haze 分層圖最短路
阿新 • • 發佈:2019-02-05
題目大意:
給你n個點,m條邊,讓你最多可以使k條邊的權值為0,問你1到n的最短路。
分析:
dijsktra的距離陣列可以多開一維,記錄已經讓幾條邊的權值為0,即分層圖最短路
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <set>
#include <vector>
using namespace std;
const int maxn = 100000 + 10 ;
typedef long long ll;
struct HeapNode
{
ll d;
int u,num;
bool operator<(const HeapNode &rhs)const
{
return d>rhs.d;
}
};
struct Edge
{
int fro,to;
ll cost;
int id;
};
const ll INF = 1e18;
struct Dij
{
vector<ll>G[maxn];
vector<Edge> edges;
ll d[maxn][15];
bool done[maxn][15];
int n,m,k_;
void init(int n,int k)
{
this->n=n;
this->k_=k;
for(int i=0;i<=n;i++) G[i].clear();
edges.clear();
}
void addedge(int from,int to,int cost,int id)
{
edges.push_back ((Edge){from,to,cost,id});
m=edges.size();
G[from].push_back(m-1);
//cout<<G[1].size()<<endl;
}
void dij(int s)
{
for(int i=0;i<=n;i++)
for(int j=0;j<=10;j++) d[i][j]=INF;
memset(done,0,sizeof(done));
priority_queue<HeapNode>Q;
d[s][0]=0;
Q.push((HeapNode){0,s,0});
while(!Q.empty())
{
HeapNode now=Q.top(); Q.pop();
int u=now.u;
int k=now.num;
if(done[u][k]) continue;
done[u][k]=true;
// cout<<u<<" "<<G[u].size()<<endl;
for(int i=0;i<G[u].size();i++)
{
Edge &e=edges[G[u][i]];
//cout<<d[e.to][k]<<" "<<d[u][k]<<" "<<e.cost<<endl;
if(d[e.to][k]>d[u][k]+e.cost)
{
d[e.to][k]=d[u][k]+e.cost;
//cout<<e.to<<" "<<u<<" "<<k<<" "<<d[e.to][k]<<endl;
Q.push((HeapNode){d[e.to][k],e.to,k});
}
if(k==k_) continue;
if(d[e.to][k+1]>d[u][k])
{
d[e.to][k+1]=d[u][k];
// cout<<e.to<<" "<<u<<" "<<k+1<<" ..."<<d[e.to][k+1]<<endl;
Q.push((HeapNode){d[e.to][k+1],e.to,k+1});
}
}
}
}
void print(int t)
{
ll ans=INF;
for(int i=0;i<=k_;i++)
{
ans=min(ans,d[t][i]);
}
printf("%lld\n",ans);
}
}D;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
D.init(n,k);
for(int i=0;i<m;i++)
{
int u,v;
ll c;
scanf("%d%d%lld",&u,&v,&c);
D.addedge(u,v,c,i);
}
D.dij(1);
D.print(n);
}
return 0;
}