POJ 2378.1655.3107 (树形DP 删点类树形DP)

本文深入探讨了信息技术领域的核心概念,包括但不限于前端开发、后端开发、移动开发、游戏开发、大数据开发等细分领域,提供了从基础知识到高级实践的全面指南。
poj2378
Tree Cutting
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3690 Accepted: 2193

Description

After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible cost, he sued Bessie to mitigate his losses. 

Bessie, feeling vindictive, decided to sabotage Farmer John's network by cutting power to one of the barns (thereby disrupting all the connections involving that barn). When Bessie does this, it breaks the network into smaller pieces, each of which retains full connectivity within itself. In order to be as disruptive as possible, Bessie wants to make sure that each of these pieces connects together no more than half the barns on FJ. 

Please help Bessie determine all of the barns that would be suitable to disconnect.

Input

* Line 1: A single integer, N. The barns are numbered 1..N. 

* Lines 2..N: Each line contains two integers X and Y and represents a connection between barns X and Y.

Output

* Lines 1..?: Each line contains a single integer, the number (from 1..N) of a barn whose removal splits the network into pieces each having at most half the original number of barns. Output the barns in increasing numerical order. If there are no suitable barns, the output should be a single line containing the word "NONE".

Sample Input

10
1 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8

Sample Output

3
8

Hint

INPUT DETAILS: 

The set of connections in the input describes a "tree": it connects all the barns together and contains no cycles. 

OUTPUT DETAILS: 

If barn 3 or barn 8 is removed, then the remaining network will have one piece consisting of 5 barns and two pieces containing 2 barns. If any other barn is removed then at least one of the remaining pieces has size at least 6 (which is more than half of the original number of barns, 5).




poj1655
Balancing Act
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8892 Accepted: 3681

Description

Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the largest tree in the forest T created by deleting that node from T. 
For example, consider the tree: 

Deleting node 4 yields two trees whose member nodes are {5} and {1,2,3,6,7}. The larger of these two trees has five nodes, thus the balance of node 4 is five. Deleting node 1 yields a forest of three trees of equal size: {2,6}, {3,7}, and {4,5}. Each of these trees has two nodes, so the balance of node 1 is two. 

For each input tree, calculate the node that has the minimum balance. If multiple nodes have equal balance, output the one with the lowest number. 

Input

The first line of input contains a single integer t (1 <= t <= 20), the number of test cases. The first line of each test case contains an integer N (1 <= N <= 20,000), the number of congruence. The next N-1 lines each contains two space-separated node numbers that are the endpoints of an edge in the tree. No edge will be listed twice, and all edges will be listed.

Output

For each test case, print a line containing two integers, the number of the node with minimum balance and the balance of that node.

Sample Input

1
7
2 6
1 2
1 4
4 5
3 7
3 1

Sample Output

1 2




poj3107
Godfather
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 4770 Accepted: 1632

Description

Last years Chicago was full of gangster fights and strange murders. The chief of the police got really tired of all these crimes, and decided to arrest the mafia leaders.

Unfortunately, the structure of Chicago mafia is rather complicated. There are n persons known to be related to mafia. The police have traced their activity for some time, and know that some of them are communicating with each other. Based on the data collected, the chief of the police suggests that the mafia hierarchy can be represented as a tree. The head of the mafia, Godfather, is the root of the tree, and if some person is represented by a node in the tree, its direct subordinates are represented by the children of that node. For the purpose of conspiracy the gangsters only communicate with their direct subordinates and their direct master.

Unfortunately, though the police know gangsters’ communications, they do not know who is a master in any pair of communicating persons. Thus they only have an undirected tree of communications, and do not know who Godfather is.

Based on the idea that Godfather wants to have the most possible control over mafia, the chief of the police has made a suggestion that Godfather is such a person that after deleting it from the communications tree the size of the largest remaining connected component is as small as possible. Help the police to find all potential Godfathers and they will arrest them.

Input

The first line of the input file contains n — the number of persons suspected to belong to mafia (2 ≤ n ≤ 50 000). Let them be numbered from 1 to n.

The following n − 1 lines contain two integer numbers each. The pair aibi means that the gangster ai has communicated with the gangster bi. It is guaranteed that the gangsters’ communications form a tree.

Output

Print the numbers of all persons that are suspected to be Godfather. The numbers must be printed in the increasing order, separated by spaces.

Sample Input

6
1 2
2 3
2 5
3 4
3 6

Sample Output

2 3



大致题意:
三道题目是一个类型的,除了输出的东西不一样,整体框架一模一样。都是给出一些连接关系,然后去掉一个点,找出去掉哪个点可以满足破除这个联系之后每个联通块的最大包含的点最少~~第一个是使最大包含的点少于或等于总点数的一半。第二个第三个都是使每个联通块中的点越少越好。

分析:
根据给出的关系建树,注意要建的是双向图,即一行输入的a,b,要add_edge(a,b)和add_edge(b,a)。
防止因为双向图而出现重复找,判一下v是否等于fa。等于的话,就是沿着这个分支找下来的,那么在这个点的时候这个分支就不去找了,并且到最下面的叶子节点处时,(因为双向)除了通往其fa的那条路是有的,其他路都没有,即可统计出这个节点分支的点数和为1,不断返回去就可以求出每个节点下面分支的节点和。n-sum就是父节点那块的点数和。以每个点为根节点的情况都判一下是否符合条件。并且记录下来就可以了。
即 删点,使剩下的分支中最大的节点数最小,深搜一次记录到叶子节点距离,再进行枚举求最大值,再更新答案。

代码都是几乎相同的

Tree Cutting
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 10010
using namespace std;

int head[N],etot,tot,n,ans[N];

struct edge{
	int v,next;
}g[500010];

void add_edge(int u,int v)
{
	g[etot].v=v;//g[etot].v是etot这条边指向的点
	g[etot].next=head[u];//g[etot].next是etot这条边的前一条边的标号(即同一个节点出去的其他分支)
	head[u]=etot++;//head[u]是u这个点出去的边的标号。
}

int dfs(int u,int fa)
{
	int child_max=-1,sum=1;//要加上自己,所以sum初始化为1
	for(int i=head[u];i!=-1;i=g[i].next)//i=-1,表示从这点出发的所有分支都搜过了。可以结束循环。
	{	
		int v=g[i].v;
		if(v==fa)//v==fa表示是来时的那条分支。不走。
			continue;
		int value=dfs(v,u);//往下搜。即搜v这个点,v这个点的来时的点是u
		if(value>child_max)
			child_max=value;//更新
		sum+=value;
	}
	if(n-sum>child_max)
		child_max=n-sum;
	if(child_max<=n/2)
		ans[tot++]=u;
	return sum;
}

int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		etot=0;
		tot=0;
		memset(head,-1,sizeof(head));//head初始化为-1 表示前面么有了
		for(int i=0;i<n-1;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			add_edge(a,b);
			add_edge(b,a);//加双向边
		}
		dfs(1,-1);//从1节点开始,将1节点的前一个节点设为-1
		if(tot==0)
			printf("NONE\n");
		else
		{
			sort(ans,ans+tot);
			for(int i=0;i<tot;i++)
			{
				printf("%d\n",ans[i]);
			}
		}
	}
	return 0;
}

Balancing Act
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 20010

int head[N],tot,etot,n;
struct edge{
	int v,next;
}g[500010];

struct minn{
	int point,value,time;
}mins;

void add_edge(int u,int v)
{
	g[etot].v=v;
	g[etot].next=head[u];
	head[u]=etot++;
}

int dfs(int u,int fa)
{
	int child_max=-1,sum=1;
	for(int i=head[u];i!=-1;i=g[i].next)
	{
		int v=g[i].v;
		if(v==fa)
			continue;
		int value=dfs(v,u);
		if(value>child_max)
			child_max=value;
		sum+=value;
	}
	if(n-sum>child_max)
		child_max=n-sum;
	if(child_max<mins.value)
	{
		mins.value=child_max;
		mins.point=u;
		mins.time=1;
	}
	else if(child_max==mins.value)
	{
		mins.time++;
		if(mins.point>u)
			mins.point=u;
	}
	return sum;
}

int main()
{
	int t;
	while(scanf("%d",&t)!=EOF)
	{
		while(t--)
		{
			memset(head,-1,sizeof(head));
			mins.value=200000;
			scanf("%d",&n);
			for(int i=0;i<n-1;i++)
			{
				int a,b;
				scanf("%d%d",&a,&b);
				add_edge(a,b);
				add_edge(b,a);
			}
			dfs(1,-1);
			printf("%d %d\n",mins.point,mins.value);
		}
	}
	return 0;
}

Godfather
#include <stdio.h>
#include <string.h>
#define N 50010
#include <algorithm>
using namespace std;

int head[N],etot,tot,n,ans[N];

struct edge{
	int v,next;
}g[500010];

void add_edge(int u,int v)
{
	g[etot].v=v;
	g[etot].next=head[u];
	head[u]=etot++;
}

struct minn{
	int value;
	int point[N];
}mins;

int dfs(int u,int fa)
{
	int child_max=-1,sum=1;
	for(int i=head[u];i!=-1;i=g[i].next)
	{
		int v=g[i].v;
		if(v==fa)
			continue;
		int value=dfs(v,u);
		if(value>child_max)
			child_max=value;
		sum+=value;
	}
	if(n-sum>child_max)
		child_max=n-sum;
	if(child_max<mins.value)
	{	
		mins.value=child_max;
		//memset(ans,0,sizeof(ans));
		tot=0;
		ans[tot++]=u;
	}
	else if(child_max==mins.value)
	{
		ans[tot++]=u;
	}
	return sum;
}

int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		memset(head,-1,sizeof(head));
		etot=0;
		mins.value=500000;
		for(int i=0;i<n-1;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			add_edge(a,b);
			add_edge(b,a);
		}
		dfs(1,-1);
		sort(ans,ans+tot);
		//printf("%d\n",tot);
		for(int i=0;i<tot;i++)
		{
			if(i==tot-1)
				printf("%d\n",ans[i]);
			else
				printf("%d ",ans[i]);
		}
	}
	return 0;
}


在充满仪式感的生活里,一款能传递心意的小工具总能带来意外惊喜。这款基于Java开发的满屏飘字弹幕工具,正是为热爱生活、乐于分享的你而来——它以简洁优雅的视觉效果,将治愈系文字化作灵动弹幕,在屏幕上缓缓流淌,既可以作为送给心仪之人的浪漫彩蛋,也能成为日常自娱自乐、舒缓心情的小确幸。 作为程序员献给crush的心意之作,工具的设计藏满了细节巧思。开发者基于Swing框架构建图形界面,实现了无边框全屏显示效果,搭配毛玻璃质感的弹幕窗口与圆润边角设计,让文字呈现既柔和又不突兀。弹幕内容精选了30条治愈系文案,从“秋天的风很温柔”到“你值得所有温柔”,涵盖生活感悟、自我关怀、浪漫告白等多个维度,每一条都能传递温暖力量;同时支持自定义修改文案库,你可以替换成专属情话、纪念文字或趣味梗,让弹幕更具个性化。 在视觉体验上,工具采用柔和色调生成算法,每一条弹幕都拥有独特的清新配色,搭配半透明渐变效果与平滑的移动动画,既不会遮挡屏幕内容,又能营造出灵动治愈的氛围。开发者还优化了弹幕的生成逻辑,支持自定义窗口大小、移动速度、生成间隔等参数,最多可同时显示60条弹幕,且不会造成电脑卡顿;按下任意按键即可快速关闭程序,操作便捷无负担。 对于Java学习者而言,这款工具更是一份优质的实战参考。源码完整展示了Swing图形界面开发、定时器调度、动画绘制、颜色算法等核心技术,注释清晰、结构简洁,哪怕是初学者也能轻松理解。开发者在AI辅助的基础上,反复调试优化细节,解决了透明度控制、弹幕碰撞、资源占用等多个问题,这份“踩坑实录”也为同项目开发提供了宝贵经验。 无论是想给喜欢的人制造浪漫惊喜,用满屏文字传递心意;还是想在工作间隙用治愈文案舒缓压力,或是作为Java学习的实战案例参考,这款满屏飘字弹幕工具都能满足你的需求。它没有复杂的操作流程,无需额外配置环境,下载即可运行,用最纯粹的设计传递最真挚的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值