1. 程式人生 > >BZOJ1916: [Usaco2010 Open]沖浪

BZOJ1916: [Usaco2010 Open]沖浪

註意 理解 技術 技術分享 dag std last stdlib.h using

n<=50000個點m<=150000的帶邊權DAG,保證1入度0,n出度0,其他點入度出度均不為0,求:從一號點開始到n,期間有可能K<=10次隨機選邊走,最壞情況下總邊權多少。

沒理解題意系列。。問了唐神T_T題目是說,這個牛已經知道會有這種情況,所以在除了K次剩下的時間裏它會選最優方案走,而如果此點最優方案比亂走方案優,那麽在最壞情況下這個點也要亂走,所以在“最優”與“亂走”去min。

f[i,j]表示點i到點n,亂j次最小邊權和,f[i,j]=min(max(f[k,j]+e(i,k)),min(f[k,j-1]+e(i,k))。

寫bfs的話註意f定義域!!!!

技術分享
 1 #include<stdio.h>
 2
#include<string.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 //#include<iostream> 6 using namespace std; 7 8 int n,m,K; 9 #define maxm 300011 10 #define maxn 50011 11 struct Edge{int to,v,next;}edge[maxm];int first[maxn],back[maxn],le=2; 12 void in(int x,int y,int v,int* first) {Edge &e=edge[le];e.to=y;e.v=v;e.next=first[x];first[x]=le++;}
13 #define LL long long 14 int du[maxn],last[maxn];LL f[maxn][13],dis[maxn]; 15 int x,y,v,que[maxn],head,tail; 16 const LL inf=1e15; 17 void play(int x) 18 { 19 for (int i=back[x];i;i=edge[i].next) 20 { 21 const Edge &e=edge[i]; 22 du[e.to]--; 23 if (!du[e.to]) que[tail++]=e.to;
24 } 25 if (x==n) 26 { 27 for (int i=1;i<=K;i++) f[x][i]=-inf; 28 f[x][0]=0;return; 29 } 30 LL Max=-inf,Min=inf; 31 for (int j=0;j<=K;j++) 32 { 33 for (int i=first[x];i;i=edge[i].next) 34 { 35 const Edge &e=edge[i]; 36 if (f[e.to][j]>=0) Max=max(Max,f[e.to][j]+e.v); 37 if (j && f[e.to][j-1]>=0) Min=min(Min,f[e.to][j-1]+e.v); 38 } 39 f[x][j]=Max<0?(Min<0?-inf:Min):(Min<0?Max:min(Max,Min)); 40 } 41 } 42 int main() 43 { 44 scanf("%d%d%d",&n,&m,&K); 45 memset(du,0,sizeof(du)); 46 for (int i=1;i<=m;i++) 47 { 48 scanf("%d%d%d",&x,&y,&v); 49 in(x,y,v,first); 50 in(y,x,v,back); 51 du[x]++; 52 } 53 head=tail=0; 54 for (int i=1;i<=n;i++) if (!du[i]) que[tail++]=i; 55 while (head!=tail) play(que[head++]); 56 printf("%lld\n",f[1][K]); 57 return 0; 58 }
View Code

BZOJ1916: [Usaco2010 Open]沖浪