WA1,4,5,7求调
查看原帖
WA1,4,5,7求调
1379306
Furinaaaa楼主2024/7/3 18:06

是不是要用状压?谢谢

#define _CRT_SECURE_NO_WARNINGS

using namespace std ; 

#include <iostream>
#include <cstring>

int n ;

//记录每个人的快乐指数
int happy[10000] ;

//链式前向星存图
typedef struct aichao
{
	int to ; //指向
	int last ; //上一条相同起点的边的编号
}E;

//存储每一条边的编号
E edge[10000] ; 

//记录当前是第几条边
int nums = 0 ; 

//head[i]记录以i为起点的最新一条边的编号
int head[10000] ; 

//加边函数
void add_edge(int start, int to)
{
	edge[nums].to = to ; 
	edge[nums].last = head[start] ;
	head[start] = nums ; 
	nums += 1 ; 

}

int mymax(int a, int b)
{
	if (a > b)
	{
		return a ;
	}
	return b ; 

}

//记录每个人的入度,看看谁没有上司
int innum[10000];
//记录每个人的出度,看看谁没有下级
int outnum [10000] ; 

//存储start为起点的子树,在start参加或者不参加时能得到的最大快乐值
int f[10000][3] ; 

int vis[10000] ;

//深搜
//希望返回start为起点的子树,在start参加或者不参加时能得到的最大快乐值
//attend = 1 表示参加,0表示不参加
int dfs(int start, int attend)
{
	//没有子节点,出口
	if (outnum[start] == 0)
	{
		//看看有没有参加
		if (attend)
		{
			return happy[start] ;
		}
		//不参加,返回0
		return 0 ; 
	}
	//有存档,直接返回
	if (f[start][attend] != -1)
	{
		return f[start][attend] ; 
	}
	//其他情况
	 
	//本身参加
	if (attend)
	{
		int temp = happy[start] ;
		//所有子节点都不能参加
		//遍历所有子节点
		for (int i = head[start]; i != -1; i = edge[i].last)
		{
			if (vis[edge[i].to] )
			{
				continue ; 
			}
			vis[edge[i].to] = 1 ; 
			temp += dfs ( edge[i].to , 0 ) ; 
			vis[edge[i].to] = 0 ; 
		}
		return f[start][attend] = temp ; 
	}

	//本身不参加
	else 
	{
		int temp = 0;
		//所有子节点都参加
		//遍历所有子节点
		for (int i = head[start]; i != -1; i = edge[i].last)
		{
			if (vis[edge[i].to])
			{
				continue;
			}
			vis[edge[i].to] = 1;
			temp +=mymax( dfs(edge[i].to, 0) , dfs (edge[i].to , 1 ) ) ; 
			vis[edge[i].to] = 0;
		}
		return f[start][attend] = temp;
	}
}
int main()
{
	//初始化
	memset ( vis , 0 , sizeof(vis) ) ; 
	memset( head , -1 , sizeof(head) ) ; 
	memset ( outnum , 0 , sizeof(outnum) ) ; 
	memset(innum, 0, sizeof(innum));
	memset ( f , -1 , sizeof(f) ) ; 
	//输入数据并存图
	scanf ("%d" , &n ) ;
	for (int i = 1; i <= n; i++)
	{
		scanf ("%d" , &happy[i] ) ; 

	}
	int start , to ;
	for (int i = 1; i <= n - 1; i++)
	{
		scanf ("%d %d" , &start , &to ) ;
		add_edge( start , to ) ; 
		outnum[start] += 1 ; 
		innum[to] += 1 ; 
	}
	//找出最大上级
	int boss ; 

	for (int i = 1; i <= n; i++)
	{
		if (innum[i] == 0)
		{
			boss = i ;
			break ; 
		}
	}
	vis[boss] = 1 ; 
	int ans = mymax ( dfs ( boss , 1 ) , dfs( boss , 0 ) ) ; 
	cout << ans ; 
	return 0 ; 

}
2024/7/3 18:06
加载中...