[USACO10OPEN]水滑梯Water Slides

洛咕

题意:E(\(1<=E<=150000\))条轨道连接着V(\(V<=50,000\))个水池,编号为1...V,轨道是单向的.从1号水池出发,经过若干条轨道,最终到达V号水池.每个水池(除了V号和1号之外),都有至少一条轨道进来和一条轨道出去,并且,从任何一个水池都能够到达V号水池.从任何一个水池出发都不可能回到这个水池.每条轨道有一个权值(\(0<= F_i <= 2,000,000,000\)),总的权值就是经过的所有轨道的权值之和.然后会有至多K(\(1<=K<=10\))次的情况,随机从某个水池选择了一条轨道(这种情况甚至会在1号水池发生),那么,在最坏情况下一次冲浪可以得到的最大权值是多少?

分析:如果没有这个\(k\)就是记忆化搜索模板题,即\(f[k][u]=max(f[k][u],dfs(k,to[i])+w[i]);\).那么我们如何处理这个\(k\)呢?理解清楚题意,\(k\)的每一次都是最坏情况,即是要取min,即\(f[k][u]=min(f[k][u],dfs(k-1,to[i])+w[i])\).这样就可以了...

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read(){
    int s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}
const int N=50005;
const int M=150005;
int tot,head[N],nxt[M],to[M],w[M];
LL f[15][N];
inline void add(int a,int b,int c){
    nxt[++tot]=head[a];head[a]=tot;
    to[tot]=b;w[tot]=c;
}
inline LL dfs(int k,int u){
    if(f[k][u])return f[k][u];
    for(int i=head[u];i;i=nxt[i])
		f[k][u]=max(f[k][u],dfs(k,to[i])+w[i]);
    if(k)
		for(int i=head[u];i;i=nxt[i])
	    	f[k][u]=min(f[k][u],dfs(k-1,to[i])+w[i]);
    return f[k][u];
}
int main(){
    int v=read(),e=read(),k=read();
    for(int i=1;i<=e;i++){
		int a=read(),b=read(),c=read();
		add(a,b,c);
    }
    printf("%lld\n",dfs(k,1));
    return 0;
}

posted on 2019-04-16 21:36  PPXppx  阅读(195)  评论(0编辑  收藏  举报