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

来源:互联网 发布:淘宝 金肉山 这么便宜 编辑:程序博客网 时间:2024/05/29 09:54
poj2378
Tree Cutting
Time Limit: 1000MS Memory Limit: 65536KTotal 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

101 22 33 44 56 77 88 99 103 8

Sample Output

38

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: 65536KTotal 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

172 61 21 44 53 73 1

Sample Output

1 2




poj3107
Godfather
Time Limit: 2000MS Memory Limit: 65536KTotal 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

61 22 32 53 43 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 10010using 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初始化为1for(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这个点的来时的点是uif(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节点的前一个节点设为-1if(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 20010int 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]);elseprintf("%d ",ans[i]);}}return 0;}


0 0
原创粉丝点击