BZOJ_1916_[Usaco2010 Open]沖浪_分層圖+拓撲排序+DP
阿新 • • 發佈:2018-06-22
src 找到 -- 無法 不可 EDA image 否則 她是 她總是從1號水池出發,抵達3號水池。如果她總是可以自己選擇,就是不會發生不能控制的情況她可以選擇從1到2(這條軌道開心值為5),再從2到3(開心值為5),總的開心值為5+5=10。但是,如過她在1號水池失去控制,直接到了3,那麽開心值為9,如果她在2號水池失去控制,她總的開心值為8。Bessie想要找到最大化開心值的方案,可以直接從1到3,這樣,如果在1號水池失去控制,這樣,她就不會在2號水池失去控制了,就能夠得到10的開心值。因此,她的開心值至少為9
* 第一樣: 一行一個整數表示在最壞情況下最大化的開心值
2 3 5
1 2 5
1 3 9
2 3 3
BZOJ_1916_[Usaco2010 Open]沖浪_分層圖+拓撲排序+DP
Description
受到秘魯的馬丘比丘的新式水上樂園的啟發,Farmer John決定也為奶牛們建 一個水上樂園。當然,它最大的亮點就是新奇巨大的水上沖浪。超級軌道包含 E (1 <= E <=150,000)條小軌道連接著V (V <= 50,000)個水池,編號為1..V。每個小軌道必須按照特定的方向運行,不能夠反向運行。奶牛們從1號水池出發,經過若幹條小軌道,最終到達V號水池。每個水池(除了V號和1號之外,都有至少一條小軌道進來和一條小軌道出去,並且,一頭奶牛從任何一個水池到達V 號水池。最後,由於這是一個沖浪,從任何一個水池出發都不可能回到這個水池) 每條小軌道從水池P_i到水池Q_i (1 <= P_i <= V; 1<= Q_i <= V; P_i != Q_i), 軌道有一個開心值F_i (0 <= F_i <= 2,000,000,000),Bessie總的開心值就是經過的所有軌道的開心值之和。Bessie自然希望越開心越好,並且,她有足夠長的時間在軌道上玩。因此,她精心地挑選路線。但是,由於她是頭奶牛,所以,會有至多K (1 <= K <= 10)次的情況,她無法控制,並且隨機從某個水池選擇了一條軌道(這種情況甚至會在1號水池發生) 如果Bessie選擇了在最壞情況下,最大化她的開心值,那麽,她在這種情況下一次沖浪可以得到的最大開心值是多少? 在樣例中,考慮一個超級軌道,包含了3個水池(在圖中用括號表示)和4條小軌道,K的值為1 (開心值在括號外表示出來,用箭頭標識)Input
* 第一行: 三個用空格隔開的整數: V, E, 和 K * 第2到第E+1行: 第i+1行包含三個用空格隔開的整數: P_i, Q_i, and F_iOutput
Sample Input
3 4 12 3 5
1 2 5
1 3 9
2 3 3
Sample Output
9
由於K很小,可以像分層圖那樣設狀態,F[i][j]表示從i到n,使用j次改變的最短路。
分兩步轉移,是否使用改變,如果使用則找一個最小的轉移,否則找一個最長的。
然後這個建反圖拓撲排序即可。
代碼:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 50050 #define M 150050 typedef long long ll; ll f[N][11],mn[N][11],mx[N][11]; int head[N],to[M],nxt[M],cnt,val[M],Q[N],l,r,in[N],n,m,K; inline void add(int u,int v,int w) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w; } int main() { scanf("%d%d%d",&n,&m,&K); int i,x,y,z,j; for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(y,x,z); in[x]++; } for(i=0;i<=K;i++) f[n][i]=0; memset(mn,0x3f,sizeof(mn)); Q[r++]=n; while(l<r) { x=Q[l++]; for(i=0;i<=K;i++) f[x][i]=min(mx[x][i],mn[x][i]); for(i=head[x];i;i=nxt[i]) { for(j=0;j<=K;j++) mx[to[i]][j]=max(mx[to[i]][j],f[x][j]+val[i]); for(j=0;j<K;j++) mn[to[i]][j]=min(mn[to[i]][j],f[x][j+1]+val[i]); if((--in[to[i]])==0) Q[r++]=to[i]; } } printf("%lld\n",f[1][0]); }
BZOJ_1916_[Usaco2010 Open]沖浪_分層圖+拓撲排序+DP