hdu3534,恶心的树形dp,需要考虑的东西太多了

来源:互联网 发布:更新淘宝手机版本 编辑:程序博客网 时间:2024/03/29 14:55

是够恶心的,然而不被恶心几次,代码能力也就练不出来了

/node[x]中记录的是:
//x的子节点通过x连接(就是在x的子树内的)的最长路径为max,条数为num,
//Max1是x的子节点到x的最长距离,num1是条数
//Max2是x的子节点到x的次长距离,num2是条数

分为,如果节点都是一样的情况,

如果节点有最长和次长距离,分情况


注意这道题倒是不用计算父亲方向的最长距离,因为是统计数量,上面那个以每一个子树为基础来统计方案才能保证统计的方案是不重不漏的。。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=200009;struct aa{int val,to,pre;}edge[maxn*2];struct bb{int max1,num1,max2,num2,m,n;}node[maxn];int n,head[maxn],tot;void add(int x,int y,int z){edge[++tot].to=y;edge[tot].pre=head[x];head[x]=tot;edge[tot].val=z;}void dfs(int u,int fa){for (int i=head[u];i;i=edge[i].pre)if (edge[i].to!=fa) dfs(edge[i].to,u);if (edge[head[u]].pre==0&&u!=1) node[u].num1=node[u].num2=1;for (int v,i=head[u];i;i=edge[i].pre)if ((v=edge[i].to)!=fa){if (node[v].max1+edge[i].val>node[u].max1) {node[u].max1=node[v].max1+edge[i].val;node[u].num1=node[v].num1;node[u].n=0;}else if (node[v].max1+edge[i].val==node[u].max1) node[u].n+=node[u].num1*node[v].num1,node[u].num1+=node[v].num1;}if (node[u].n==0){for (int v,i=head[u];i;i=edge[i].pre)if (fa!=(v=edge[i].to)){if (node[v].max1+edge[i].val==node[u].max1)continue;if (node[v].max1+edge[i].val>node[u].max2){node[u].max2=node[v].max1+edge[i].val;node[u].num2=node[v].num1;}else if (node[v].max1+edge[i].val==node[u].max2) node[u].num2+=node[v].num1;}if (node[u].max2) {node[u].n=node[u].num1*node[u].num2;node[u].m=node[u].max1+node[u].max2;}else node[u].n=node[u].num1,node[u].m=node[u].max1;} else node[u].m=node[u].max1*2;}int main(){while (scanf("%d",&n)==1){memset(head,0,sizeof(head));memset(node,0,sizeof(node));tot=0;for (int i=1;i<n;i++) {int x,y,z;scanf("%d%d%d",&x,&y,&z);add(x,y,z);add(y,x,z);}dfs(1,0);int ansn=0,ansm=0;for (int i=1;i<=n;i++){if (node[i].m>ansm){ansm=node[i].m;//<span style="color: rgb(0, 128, 0); line-height: 1.5; font-family: 'Courier New'; white-space: pre-wrap;">该<strong>结点为根</strong>的子树中,包含该结点的最长路径长度</span>ansn=node[i].n;}else if (node[i].m==ansm) ansn+=node[i].n;}printf("%d %d\n",ansm,ansn);}return 0;}


0 0