2018南京網路賽 L Magical Girl Haze(最短路、堆、狀態轉移)
阿新 • • 發佈:2018-11-02
我們設定dis[i][k]表示走到第i號點,免費經過了k條邊的最短路。
對於我們當前找到的終點,嘗試起點的狀態去更新,不選擇此條邊免費的狀態和選擇此條邊免費的狀態,再將這兩個狀態壓入佇列去更新可以到達的其他狀態。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<set> #define maxn 200005 #define INF 0x3f3f3f3f #define MOD 1000000007 #define LL long long #define ev 2.71828182 using namespace std; const double PI=acos(-1.0); int t,n,m,k; struct node { int from,cs; LL w; friend bool operator <(node a,node b) { return a.w>b.w; } }; struct knode { int to,w; }; vector<knode>v[maxn]; int dis[maxn][20];//dis[i][k]表示走到i點,k條邊置0時的最短距離 bool book[maxn][20]; void dijkstra() { memset(dis,0x3f,sizeof(dis)); memset(book,false,sizeof(book)); priority_queue<node>q; node h={1,0,0}; q.push(h); while(!q.empty()) { node t=q.top(); q.pop(); if(book[t.from][t.cs]) continue; book[t.from][t.cs]=true; for(int i=0;i<v[t.from].size();i++) { int mb=v[t.from][i].to; int bw=v[t.from][i].w; if(dis[mb][t.cs]>t.w+bw) { dis[mb][t.cs]=t.w+bw; q.push(node{mb,t.cs,dis[mb][t.cs]}); } if(t.cs+1<=k) { if(dis[mb][t.cs+1]>t.w+0) { dis[mb][t.cs+1]=t.w; q.push(node{mb,t.cs+1,dis[mb][t.cs+1]}); } } } } } int main() { int t; cin>>t; while(t--) { cin>>n>>m>>k; for(int i=0;i<maxn;i++) v[i].clear(); for(int i=0;i<m;i++) { int a,b,c; cin>>a>>b>>c; knode z; z.to=b;z.w=c; v[a].push_back(z); } dijkstra(); cout << dis[n][k] << endl; } return 0; }