比赛 20101118 评测结果 AAAWWWEEWE
题目名称 情敌 最终得分 30
用户昵称 苏轼 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2010-11-18 09:55:39
显示代码纯文本
#include <stdio.h>

#define MAXN 55
#define MAXV 105
#define oo 0x7fffffff

int N,M,V1,V2,sum;
int d[MAXN][MAXV][MAXV],dd[MAXN][MAXV][MAXV];
int adj[MAXN][MAXN];
bool nen[MAXN];
int w[MAXN],v[MAXN];
int fo[MAXN];
int tmp=0;

inline void add(const int &a,const int &b)
{
	adj[a][++adj[a][0]]=b;
	nen[b]=true;
}

inline void Max(int &a,int b)
{
	if (b>a) a=b;
}

inline void dp(int u)
{
	for(int j=0;j<w[u];j++)
		for(int k=0;k<w[u]*2;k++)
			d[u][j][k]=dd[u][j][k]=-oo;
	for(int j=w[u];j<=V1;j++)
		for(int k=0;k<=V2;k++)
			d[u][j][k]=d[fo[u]][j-w[u]][k]+w[u];
	for(int k=1;k<=adj[u][0];k++)
	{
		int i=adj[u][k];
		fo[i]=tmp;
		tmp=i;
		for(int j=0;j<=V1;j++)
			for(int k=0;k<=V2;k++)
			{
				d[i][j][k]=d[fo[i]][j][k];
				if (j>=v[i])
					Max(d[i][j][k],d[fo[i]][j-v[i]][k]+w[i]);
				if (k>=2*v[i])
					Max(d[i][j][k],d[fo[i]][j][k-2*v[i]]+w[i]);
			}
	}	
	for(int j=0;j<V1;j++)
		for(int k=w[u]*2;k<=V2;k++)
			dd[u][j][k]=d[fo[u]][j][k-w[u]*2]+w[u];
	for(int k=1;k<=adj[u][0];k++)
	{
		int i=adj[u][k];
		for(int j=0;j<=V1;j++)
			for(int k=0;k<=V2;k++)
			{
				dd[i][j][k]=dd[fo[i]][j][k];
				if (k>=2*v[i])
					Max(dd[i][j][k],dd[fo[i]][j][k-2*v[i]]+w[i]);
			}
	}
	for(int j=0;j<=V1;j++)
		for(int k=0;k<=V2;k++)
		{
			Max(d[u][j][k],d[tmp][j][k]);
			Max(d[u][j][k],d[fo[u]][j][k]);
			Max(d[u][j][k],dd[u][j][k]);
		}
}

int main()
{
	freopen("rival.in","r",stdin);
	freopen("rival.out","w",stdout);
	scanf("%d%d",&V1,&V2);
	scanf("%d%d",&N,&M);
	for(int i=1;i<=N;i++)
	{
		scanf("%d%d",w+i,v+i);
		sum+=w[i];
	}
	for(int i=0;i<M;i++)
	{
		int c,tot;
		scanf("%d%d",&c,&tot);
		for(int j=0;j<tot;j++)
		{
			int x;
			scanf("%d",&x);
			add(c,x);
		}
	}
	fo[1]=tmp;
	for(int i=1;i<=N;i++)
		if (!nen[i]&&adj[i][0]==0)
		{
			fo[i]=tmp;
			tmp=i;
			for(int j=0;j<=V1;j++)
				for(int k=0;k<=V2;k++)
				{
					d[i][j][k]=d[fo[i]][j][k];
					if (j>=v[i])
						Max(d[i][j][k],d[fo[i]][j-v[i]][k]+w[i]);
					if (k>=2*v[i])
						Max(d[i][j][k],d[fo[i]][j][k-2*v[i]]+w[i]);
				}
		}
		else if (adj[i][0])
		{
			fo[i]=tmp;
			tmp=i;
			dp(i);
			tmp=i;
		}
	printf("%d\n",sum-d[tmp][V1][V2]);
	return 0;
}