ACM-ICPC 2018 南京赛区网络预赛 L.Magical Girl Haze
L.Magical Girl Haze
题目链接:
https://nanti.jisuanke.com/t/31001
Description
There are N cities in the country, and M directional roads from u to v(1≤u,v≤n). Every road has a distance ci. Haze is a Magical Girl that lives in City 1, she can choose no more than K roads and make their distances become 0. Now she wants to go to City N, please help her calculate the minimum distance.
Input
The first line has one integer T(1≤T≤5), then following T cases.
For each test case, the first line has three integers N,Mand K.
Then the following M lines each line has three integers, describe a road, Ui,Vi,Ci. There might be multiple
edges between u and v.
It is guaranteed that N≤100000,M≤200000,K≤10,
0≤Ci≤1e9.There is at least one path between City 1 and City N.
Output
For each test case, print the minimum distance.
Sample Input
1
5 6 1
1 2 2
1 3 4
2 4 3
3 4 1
3 5 6
4 5 2
Sample Output
3
题意
给你N个点,M条有向边,你有K次机会可以把任意一条路的权值变为0,输出1到N的最短路。
题解
dis[i][j]表示源点到i点使用了j次机会把j条路的权值变为0的最短路,这样每条路就可以扩展出两种状态:一种是接下来一条路使用一次机会dis[next][j+1],另一种是不使用dis[next][j]。然后跑SPFA。此处SPFA有一个优化:每次把点入队之前,考虑即将入队的dis值与队头的dis值的大小,若即将入队的dis值小于队头的dis值,就插入队头,否则就插入队尾(双端队列实现)。
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int INF=0x3f3f3f3f; 5 const int maxn=1e6+5; 6 struct Edge{ 7 int e,w; 8 Edge * pNext; 9 }; 10 struct Node{ 11 int u,k; 12 Node(int uu,int kk):u(uu),k(kk){} 13 Node(){} 14 }; 15 Edge G[200005],* p[maxn],*head[maxn]; 16 LL dis[maxn][15]; 17 int T,N,M,K,vis[maxn][15]; 18 void SPFA(int v){ 19 deque<Node> q; 20 int s,e,w,k; 21 for(int i=1;i<=N;++i){ 22 for(int j=0;j<=K;++j){ 23 dis[i][j]=INF; 24 vis[i][j]=0; 25 } 26 head[i]=p[i]; 27 } 28 q.push_front(Node(v,0)); 29 dis[v][0]=0; 30 vis[v][0]=1; 31 while(!q.empty()){ 32 s=q.front().u; 33 k=q.front().k; 34 q.pop_front(); 35 vis[s][k]=0; 36 head[s]=p[s]; 37 while(head[s]){ 38 e=head[s]->e; 39 w=head[s]->w; 40 if(dis[e][k]>dis[s][k]+w){ 41 dis[e][k]=dis[s][k]+w; 42 if(!vis[e][k]){ 43 vis[e][k]=1; 44 if(!q.empty()){ 45 if(dis[e][k]>dis[q.front().u][q.front().k]){ 46 q.push_back(Node(e,k)); 47 }else{ 48 q.push_front(Node(e,k)); 49 } 50 }else{ 51 q.push_back(Node(e,k)); 52 } 53 } 54 } 55 if(k+1<=K&&dis[e][k+1]>dis[s][k]){ 56 dis[e][k+1]=dis[s][k]; 57 if(!vis[e][k+1]){ 58 vis[e][k+1]=1; 59 if(!q.empty()){ 60 if(dis[e][k+1]>dis[q.front().u][q.front().k]){ 61 q.push_back(Node(e,k+1)); 62 }else{ 63 q.push_front(Node(e,k+1)); 64 } 65 }else{ 66 q.push_back(Node(e,k+1)); 67 } 68 } 69 } 70 head[s]=head[s]->pNext; 71 } 72 } 73 } 74 int main(){ 75 scanf("%d",&T); 76 while(T--){ 77 int cnt=0,u,v,c; 78 memset(G,0,sizeof(G)); 79 memset(p,0,sizeof(p)); 80 scanf("%d%d%d",&N,&M,&K); 81 for(int i=0;i<M;++i){ 82 scanf("%d%d%d",&u,&v,&c); 83 G[cnt].e=v; 84 G[cnt].w=c; 85 G[cnt].pNext=p[u]; 86 p[u]=&G[cnt]; 87 cnt++; 88 } 89 SPFA(1); 90 sort(dis[N],dis[N]+K+1); 91 printf("%lld\n",dis[N][0]); 92 } 93 return 0; 94 }