码迷,mamicode.com
首页 > 其他好文 > 详细

[poj3107]Godfather树形dp

时间:2017-08-23 19:04:36      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:mat   树的重心   lag   main   type   ++   set   答案   bool   

题意:求树的重心

解题关键:想树的结构,删去某个点后只剩下它的子树和原树-此树所形成的数,然后第一次dp求每个子树的节点个数,第二次dp求解答案即可。

此题一开始一直T,后来加了输入挂才过,第一次见卡cin+关同步的题目。

用scanf试了一下,也可以过,5s,看来cin关同步和scanf差距也是蛮大的。

一:219ms

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<iostream>
 7 #define inf 0x3f3f3f3f
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn=1e5+3;
11 int head[maxn],tot,n;
12 struct edge{
13     int to;
14     int nxt;
15     int w;
16 }e[maxn<<1];
17 void add_edge(int u,int v,int w){
18     e[tot].to=v;
19     e[tot].w=w;
20     e[tot].nxt=head[u];
21     head[u]=tot++;
22 }
23 int dp[maxn<<2],cnt[maxn];
24 void dfs(int u,int fa){
25     cnt[u]=1;
26     for(int i=head[u];i!=-1;i=e[i].nxt){
27         int v=e[i].to;
28         if(v==fa) continue;
29         dfs(v,u);
30         cnt[u]+=cnt[v];
31     }
32     dp[u]=n-cnt[u];
33     for(int i=head[u];i!=-1;i=e[i].nxt){
34         int v=e[i].to;
35         if(v==fa) continue;
36         dp[u]=max(dp[u],cnt[v]);
37     }
38 }
39 
40 inline int read(){
41     char k=0;char ls;ls=getchar();for(;ls<0||ls>9;k=ls,ls=getchar());
42     int x=0;for(;ls>=0&&ls<=9;ls=getchar())x=x*10+ls-0;
43     if(k==-)x=0-x;return x;
44 }
45 int main(){
46     //ios::sync_with_stdio(0);
47     //cin.tie(0);
48     //cout.tie(0);
49     n=read();
50     memset(head,-1,sizeof head);
51     tot=0;
52     int a,b;
53     for(int i=0;i<n-1;i++){
54         //scanf("%d%d",&a,&b);
55         //cin>>a>>b;
56         a=read();
57         b=read();
58         add_edge(a,b,1);
59         add_edge(b,a,1);
60     }
61     dfs(1,-1);
62     int ans=inf;
63     for(int i=1;i<=n;i++){
64         ans=min(ans,dp[i]);
65     }
66     bool flag=false;
67     for(int i=1;i<=n;i++){
68         if(dp[i]==ans){
69             if(flag) printf(" ");
70             printf("%d",i);
71             flag=true;
72         }
73     }
74     printf("\n");
75     return 0;
76 }

 两个dfs分开的形式,练习一下。读入挂将*10变为(x<<3)+(x<<1),变为188ms了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<iostream>
 7 #define inf 0x3f3f3f3f
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn=1e5+3;
11 int head[maxn],tot,n;
12 struct edge{
13     int to;
14     int nxt;
15     int w;
16 }e[maxn<<1];
17 
18 void add_edge(int u,int v,int w){
19     e[tot].to=v;
20     e[tot].w=w;
21     e[tot].nxt=head[u];
22     head[u]=tot++;
23 }
24 int dp[maxn<<2],cnt[maxn];
25 
26 void dfs(int u,int fa){
27     cnt[u]=1;
28     for(int i=head[u];i!=-1;i=e[i].nxt){
29         int v=e[i].to;
30         if(v==fa) continue;
31         dfs(v,u);
32         cnt[u]+=cnt[v];
33     }
34 }
35 
36 void dfs2(int u,int fa){    
37     dp[u]=n-cnt[u];
38     for(int i=head[u];i!=-1;i=e[i].nxt){
39         int v=e[i].to;
40         if(v==fa) continue;
41         dfs2(v,u);
42         dp[u]=max(dp[u],cnt[v]);
43     }
44 }
45 
46 inline int read(){
47     char k=0;char ls;ls=getchar();for(;ls<0||ls>9;k=ls,ls=getchar());
48     int x=0;for(;ls>=0&&ls<=9;ls=getchar())x=(x<<3)+(x<<1)+ls-0;
49     if(k==-)x=0-x;return x;
50 }
51 int main(){
52     //ios::sync_with_stdio(0);
53     //cin.tie(0);
54     //cout.tie(0);
55     n=read();
56     memset(head,-1,sizeof head);
57     tot=0;
58     int a,b;
59     for(int i=0;i<n-1;i++){
60         //scanf("%d%d",&a,&b);
61         //cin>>a>>b;
62         a=read();
63         b=read();
64         add_edge(a,b,1);
65         add_edge(b,a,1);
66     }
67     dfs(1,-1);
68     dfs2(1,-1);
69     int ans=inf;
70     for(int i=1;i<=n;i++){
71         ans=min(ans,dp[i]);
72     }
73     bool flag=false;
74     for(int i=1;i<=n;i++){
75         if(dp[i]==ans){
76             if(flag) printf(" ");
77             printf("%d",i);
78             flag=true;
79         }
80     }
81     printf("\n");
82     return 0;
83 }

 

[poj3107]Godfather树形dp

标签:mat   树的重心   lag   main   type   ++   set   答案   bool   

原文地址:http://www.cnblogs.com/elpsycongroo/p/7419509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!