bzoj1579: [Usaco2009 Feb]Revamping Trails 道路升級
阿新 • • 發佈:2017-09-23
cpp 它的 digi ostream 不知道 分開 sam using char
1 2 10
2 4 10
1 3 1
3 4 100
1579: [Usaco2009 Feb]Revamping Trails 道路升級
Time Limit: 10 Sec Memory Limit: 64 MBDescription
每天,農夫John需要經過一些道路去檢查牛棚N裏面的牛. 農場上有M(1<=M<=50,000)條雙向泥土道路,編號為1..M. 道路i連接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)時間單位用道路i從P1_i走到P2_i或者從P2_i 走到P1_i 他想更新一些路經來減少每天花在路上的時間.具體地說,他想更新K (1 <= K <= 20)條路經,將它們所須時間減為0.幫助FJ選擇哪些路經需要更新使得從1到N的時間盡量少.
Input
* 第一行: 三個空格分開的數: N, M, 和 K * 第2..M+1行: 第i+1行有三個空格分開的數:P1_i, P2_i, 和 T_i
Output
* 第一行: 更新最多K條路經後的最短路經長度.
Sample Input
4 4 11 2 10
2 4 10
1 3 1
3 4 100
Sample Output
1 HINTK是1; 更新道路3->4使得從3到4的時間由100減少到0. 最新最短路經是1->3->4,總用時為1單位. N<=10000
Solution
用二維數組dis[i][j]表示1到i點用了j次道路升級後的最短路。
相當於建了一個分層圖,除了第0層,每個點的dis值由上一層或所在的這一層更新而來,因為dijstra(很久都不會dijstra了,今天又去學了一下,覺得dijstra和SPFA的區別就是,dijstra用最小的dis去更新其它的dis,SPFA則不保證)每次找到最小的dis去更新其它的dis,所以第一次到達n號節點找到的就是最短路。
看到別人的題解裏說SPFA要麻煩一點,需要跑k次,我不知道為什麽SPFA不能像dijstra一樣用二維的吶。
#include<algorithm> #include<iostream> #include<cstring> // #include<cstdlib> #include<cstdio> #include<queue> #define nn 10010 #define mm 100010 using namespace std; int e=0,k; int dis[nn][25],fir[nn],nxt[mm],to[mm],w[mm]; struct node{ int x,k,d; bool operator<(const node&b)const{ //priority——queue需要重載小於號 return d>b.d; } }; priority_queue<node> q; int read() { int ans=0,f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} while(isdigit(ch)) {ans=ans*10+ch-‘0‘;ch=getchar();} return ans*f; } void add(int u,int v,int ww) { nxt[++e]=fir[u];fir[u]=e;to[e]=v;w[e]=ww; nxt[++e]=fir[v];fir[v]=e;to[e]=u;w[e]=ww; } int dijstra(int n) { memset(dis,127,sizeof(dis)); q.push((node){1,0,0}); dis[1][0]=0; while(!q.empty()) { node o=q.top();q.pop(); if(o.d!=dis[o.x][o.k]) continue; if(o.x==n) return o.d; for(int i=fir[o.x];i;i=nxt[i]) { if(dis[to[i]][o.k]>dis[o.x][o.k]+w[i]) { dis[to[i]][o.k]=dis[o.x][o.k]+w[i]; q.push((node){to[i],o.k,dis[to[i]][o.k]}); } if(o.k<k&&dis[to[i]][o.k+1]>dis[o.x][o.k]) { dis[to[i]][o.k+1]=dis[o.x][o.k]; q.push((node){to[i],o.k+1,dis[to[i]][o.k+1]}); } } } } int main() { int n,m,u,v,ww; n=read();m=read();k=read(); for(int i=1;i<=m;i++) { u=read();v=read();ww=read(); add(u,v,ww); } printf("%d",dijstra(n)); return 0; }
bzoj1579: [Usaco2009 Feb]Revamping Trails 道路升級