【树形dp】PKU-3107-Godfather
2012-03-23 14:43
260 查看
题目要求找到这样的一个点,当删除这个点后使得形成的深林的最大的子树的节点最小。而且这些点可能有多个,请一一输出。其实这道题就是1655的翻版,不过在这道题中不能用stl中的vector,因为会超时,所以要用邻接表来存储。
题目
题目
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<map> #include<stack> using namespace std; #define FRE freopen("a.txt","r",stdin); #define inf 999999999 #define N 50005 struct { int v,next; }edge[2*N]; int k,head ; void addedge(int u,int v) { edge[k].v=v; edge[k].next=head[u]; head[u]=k++; } int n,dp ; int dfs(int now,int pre) { int t,m=-1,sum=1; for(int i=head[now];i!=-1;i=edge[i].next) { int u=edge[i].v; if(u==pre)continue; m=max(m,t=dfs(u,now)); //找以now为跟的树的含节点数最多的子树 sum+=t; //以now为跟的树的节点和,不过这里不包括以pre为跟的子树的节点数 } dp[now]=max(n-sum,m); //n-sum表示以pre为跟的子树的节点数,m表示以now为跟的树的含节点数最多的子树 return sum; } int main() { //FRE; while(scanf("%d",&n)!=EOF) { memset(head,-1,sizeof(head)); for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } dfs(1,0); int m=inf; vector<int> p; p.clear(); for(int i=1;i<=n;i++) { if(dp[i]==m)p.push_back(i); if(dp[i]<m) { p.clear(); p.push_back(i); m=dp[i]; } } int flag=0; for(int i=0;i<p.size();i++) { if(flag)printf(" "); flag=1; printf("%d",p[i]); } printf("\n"); } return 0; }
相关文章推荐
- POJ 3107-Godfather(树形dp)
- poj 3107 Godfather(树形dp)
- poj 3107 Godfather(树形DP)
- poj 3107 Godfather(树形DP,点的个数较多, 删点使得剩余部分结点最多的最小值)
- poj 3107 Godfather(树形dp,树的重心)
- POJ 3107 Godfather 【树形DP】
- Godfather - POJ 3107 树形dp
- poj 3107 Godfather(树形dp)
- POJ 3107 Godfather(树形dp)
- poj 3107 Godfather (树形dp)
- POJ 3107 Godfather(树形DP)
- 【dp每一天】POJ - 3107 Godfather (树形dp)
- POJ 3107 Godfather(树形DP)
- POJ 3107 Godfather (树形dp)
- poj 3107 Godfather 求树的所有重心 树形DP
- POJ 3107 Godfather (树形DP)
- POJ 3107 - Godfather 树形DP..vector慎用...
- 【POJ】3107 Godfather 树形dp
- poj 3107 Godfather(树形dp)
- POJ 3107 Godfather (水题,树形DP)