[HAOI2010] software installation

Keywords: PHP

[HAOI2010] software installation

At the beginning, I didn't understand the problem. I thought it was a tree shaped dependent backpack. After I finished typing W40, I found that it would return. To use tarjan to shrink the point and run the backpack, I need to establish a virtual node 0 to connect all the subgraphs (pay attention to the location of the connection).

But I had a detail card for a long time:

Error demonstration:

1 for(int i=1;i<=n;i++)//This will cause 0 to connect points (or rings) that are not in degrees 0
2     if(!Dsn[i])
3     {
4         tarjan(i);
5         add(0,i);
6     }

Correct code:

1     for(int i=1;i<=tot;i++)
2     if(!du[i])
3         add2(0,i);

At the reduction point, the entry degree of each scc is recorded, and 0 is directly connected to the scc with the entry degree of 0.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define MAXN 110
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
struct edge
{
	int u,v,nxt;
	#define u(x) ed[x].u
	#define v(x) ed[x].v
	#define n(x) ed[x].nxt
	#define u2(x) ed2[x].u
	#define v2(x) ed2[x].v
	#define n2(x) ed2[x].nxt
}ed[5010],ed2[5010];
int first[MAXN],num_e;
#define f(x) first[x]
int first2[MAXN],num_e2;
#define f2(x) first2[x]
int n,m;
int w[MAXN],v[MAXN],d[MAXN];
int w2[MAXN],v2[MAXN];

int Dsn[MAXN],Low[MAXN],cnt;
int stack[MAXN],top;
bool vi[MAXN];
int belong[MAXN],tot;
int du[MAXN];
vector<int> scc[MAXN];
void tarjan(int x)
{
	Dsn[x]=++cnt;Low[x]=cnt;
	stack[++top]=x;
	vi[x]=1;
	for(int i=f(x);i;i=n(i))
		if(!Dsn[v(i)])tarjan(v(i)),Low[x]=min(Low[x],Low[v(i)]);
		else if(vi[v(i)])Low[x]=min(Low[x],Low[v(i)]);
	if(Dsn[x]==Low[x])	
	{
		++tot;vi[x]=0;
		while(stack[top]!=x)
		{
			vi[stack[top]]=0;
			scc[tot].push_back(stack[top]);
			belong[stack[top--]]=tot;
		}
		scc[tot].push_back(stack[top]);
		belong[stack[top--]]=tot;
	}
}
inline void add(int u,int v)
{
	++num_e;
	u(num_e)=u;
	v(num_e)=v;
	n(num_e)=f(u);
	f(u)=num_e;
}
inline void add2(int u,int v)
{
	++num_e2;
	u2(num_e2)=u;
	v2(num_e2)=v;
	n2(num_e2)=f2(u);
	f2(u)=num_e2;
}
int f[MAXN][510];
void dfs(int x)
{
	f[x][w2[x]]=v2[x];
	for(int i=f2(x);i;i=n2(i))
	{
		dfs(v2(i));
		for(int j=m;j>=w2[x];j--)
			for(int k=0;k<=m;k++)
			{
				if(j+k>m)break;
				f[x][j+k]=max(f[x][j+k],f[x][j]+f[v2(i)][k]);	
			}
	}
}
signed main()
{
//	freopen("in.txt","r",stdin);

	cin>>n>>m;
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	for(int i=1;i<=n;i++)scanf("%d",&v[i]);
	for(int i=1;i<=n;i++){scanf("%d",&d[i]);if(d[i])add(d[i],i);}

	for(int i=1;i<=n;i++)
	if(!Dsn[i])
		tarjan(i);
	
	for(int i=1;i<=num_e;i++)
	if(belong[u(i)]!=belong[v(i)])
	{
		add2(belong[u(i)],belong[v(i)]);	
		du[belong[v(i)]]++;
	}
	for(int i=1;i<=tot;i++)
	if(!du[i])
		add2(0,i);
	
	for(int i=1;i<=tot;i++)
	{
		for(int j=0;j<scc[i].size();j++)
		{
			w2[i]+=w[scc[i][j]];
			v2[i]+=v[scc[i][j]];
		}
	}
	dfs(0);
	int ans=0;
	for(int i=1;i<=m;i++)ans=max(ans,f[belong[0]][i]);
	printf("%d\n",ans);
}

Posted by libertyct on Tue, 29 Oct 2019 11:51:48 -0700