1. 程式人生 > >2018南京網路賽L題 Magical Girl Haze 分層圖最短路

2018南京網路賽L題 Magical Girl Haze 分層圖最短路

題目大意:
給你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; }