您的位置:首页 > 其它

[SDOI2006]保安站岗

2017-03-07 19:46 239 查看
对每个节点存三个状态:未保护(但子树完全保证符合);被保护;自己站一个警察。

然后就好了

n才1500让我开始想到别的地方去了QAQ

(TMD)INF比-1好用到不知道哪里去了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(j,k,l) for (long long j=k;j<=l;++j)
#define red(j,k,l) for (long long j=k;j>=l;--j)
#define N 1505
#define inf 100000009

using namespace std;
long long n,cnt,a
,pi
,dp
[3],st
,ne[2*N],to[2*N];

void add(long long k,long long l){

to[++cnt]=l;
ne[cnt]=st[k];
st[k]=cnt;

}

long long min(long long a,long long b){

return (((a)>(b))?(b):(a));

}

void Dp(long long k){

if (st[k]==0){

dp[k][0]=0; //未保护
dp[k][1]=inf; //被保护
dp[k][2]=a[k]; //自己选
return;

}
dp[k][0]=0,dp[k][1]=0,dp[k][2]=a[k];
long long mxm=inf;
for (long long i=st[k];i;i=ne[i]){

Dp(to[i]);
dp[k][0]+=dp[to[i]][1];
dp[k][1]+=min(dp[to[i]][1],dp[to[i]][2]);
dp[k][2]+=min(min(dp[to[i]][0],dp[to[i]][1]),dp[to[i]][2]);
mxm=min(mxm,dp[to[i]][2]-dp[to[i]][1]);

}
if (mxm>0) dp[k][1]+=mxm;
return;

}

int main(){

scanf("%lld",&n);
rep(i,1,n){

long long k,l;
scanf("%lld",&k);
scanf("%lld%lld",a+k,&l);
rep(j,1,l){

long long p;
scanf("%lld",&p);
add(k,p);pi[p]++;

}

}
long long rt=0;
rep(i,1,n) if (pi[i]==0) rt=i;
Dp(rt);
printf("%lld\n",min(dp[rt][1],dp[rt][2]));
system("pause");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: