您的位置:首页 > 理论基础 > 计算机网络

ACM2012长春赛区网络赛——1010

2012-09-09 00:42 309 查看
首先一次dfs找到1到n的路径并记录这条路径上的点以及路径长度,这条路径只走一遍,其他走过的路径都需要走两遍,如果当前时间已经大于t了即无解,否则对于每个路径上的点,以这个点为根节点在不包含路径上其他点的树上跑一次树形背包,我的背包写得很丑,是O(n^3)的,但是还是过了,最后对于每个节点的情况再组合在一起来个背包即可

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct point
{
int end,next,length;
}f[201];

int n,t,i,j,a[101],u,v,l,k,begin[101],ans[260];
bool p[101],vis[101];
int dp[101][260];

void insert(int u,int v,int l)
{
f[k].end=v;
f[k].next=begin[u];
f[k].length=l;
begin[u]=k++;
}

bool dfs(int u)
{
p[u]=1;
if(u==n)return true;
int i,v;
for(i=begin[u];i!=-1;i=f[i].next)
{
v=f[i].end;
if(!p[v])
{
if(dfs(v))
{
t-=f[i].length;
return true;
}
}
}
p[u]=0;
return false;
}

void dfs2(int u)
{
vis[u]=1;
int i,v,j,k;
for(i=0;i<=t;i++)
dp[u][i]=a[u];
for(i=begin[u];i!=-1;i=f[i].next)
{
v=f[i].end;
if(vis[v])continue;
dfs2(v);
for(j=t;j>=0;j--)
{
for(k=f[i].length;k<=j;k++)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k-f[i].length]);
}
}
}

int main()
{
while(scanf("%d%d",&n,&t)==2)
{
k=0;
memset(begin,-1,sizeof(begin));
for(i=1;i<n;i++)
{
scanf("%d%d%d",&u,&v,&l);
insert(u,v,l);
insert(v,u,l);
}
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
memset(p,0,sizeof(p));
dfs(1);
if(t<0)
{
puts("Human beings die in pursuit of wealth, and birds die in pursuit of food!");
continue;
}
t=t/2;
memset(ans,0,sizeof(ans));
memset(dp,0,sizeof(dp));
memcpy(vis,p,sizeof(vis));
for(i=1;i<=n;i++)
if(p[i])
{
dfs2(i);
for(j=t;j>=0;j--)
{
for(k=0;k<=j;k++)
{
ans[j]=max(ans[j],ans[j-k]+dp[i][k]);
}
//printf("%d:%d\n",j,ans[j]);
}
}
printf("%d\n",ans[t]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: