zoukankan      html  css  js  c++  java
  • 树形dp(C

    题目链接:https://cn.vjudge.net/contest/277955#problem/C

    题目大意:输入n,代表有n个城市,然后再输入n-1条有向边,然后让你找出一个改变边数的最小值,使得某个城市能够到达剩余的所有城市,然后问这样的城市有多少个,并且输出这些城市的编号。

     具体思路:我们首先按照题目给的条件建好边,然后树就建好了,对于当前的某个节点,如果这个点要是能够到达剩余的所有城市,从这个节点往上的话,这个节点连接的父亲节点的这条边应该是是从子节点到父节点的。从这个节点往下的话,这个节点往下的话,他所连接的子节点应该是往下的,具体思路就来了。

    用dp[i][0]代表当前的节点往下连接他的子树所需的最小的改变的边的数目。dp[i][1]代表的是当前的子节点往上连接他的父亲节点所需的改变最小的边数。

    第二种情况,dp[rt][0]+=dp[soon][0];

    第一种情况,dp[soon][1]+=dp[rt][1]+dp[rt][0]-edge[i].cost-dp[to][0]+(edge[i].cost==1?0:1).

     AC代码:

     1 #include<iostream>
     2 #include<cmath>
     3 #include<stack>
     4 #include<stdio.h>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<vector>
     8 #include<cstring>
     9 using namespace std;
    10 # define inf 0x3f3f3f3f
    11 # define ll long long
    12 const int maxn = 4e5+100;
    13 struct node
    14 {
    15     int nex;
    16     int to;
    17     int cost;
    18 } edge[maxn];
    19 int num,head[maxn],dp[maxn][3],father[maxn];
    20 int sto[maxn];
    21 void init()
    22 {
    23     num=0;
    24     memset(head,-1,sizeof(head));
    25     memset(dp,0,sizeof(dp));
    26 }
    27 void addedge(int fr,int to,int cost)
    28 {
    29     edge[num].to=to;
    30     edge[num].nex=head[fr];
    31     edge[num].cost=cost;
    32     head[fr]=num++;
    33 }
    34 void dfs1(int fr,int rt)
    35 {
    36     for(int i=head[fr]; i!=-1; i=edge[i].nex)
    37     {
    38         int to=edge[i].to;
    39         if(to==rt)
    40             continue;
    41         dfs1(to,fr);
    42         dp[fr][0]+=dp[to][0]+edge[i].cost;
    43     }
    44 }
    45 void dfs2(int fr,int rt)
    46 {
    47     for(int i=head[fr]; i!=-1; i=edge[i].nex)
    48     {
    49         int to=edge[i].to;
    50         if(to==rt)
    51             continue;
    52         dp[to][1]+=dp[fr][1]+dp[fr][0]-dp[to][0]+(edge[i].cost==1?0:1)-edge[i].cost;
    53         dfs2(to,fr);
    54     }
    55 }
    56 int main()
    57 {
    58     init();
    59     int n;
    60     scanf("%d",&n);
    61     int t1,t2;
    62     for(int i=1; i<=n-1; i++)
    63     {
    64         scanf("%d %d",&t1,&t2);
    65         addedge(t1,t2,0);
    66         addedge(t2,t1,1);
    67     }
    68     dfs1(1,-1);
    69     dfs2(1,-1);
    70     int minn=inf;
    71     for(int i=1; i<=n; i++)
    72     {
    73         minn=min(minn,dp[i][0]+dp[i][1]);
    74     }
    75     printf("%d
    ",minn);
    76     int num=0;
    77     for(int i=1; i<=n; i++)
    78     {
    79         if(dp[i][0]+dp[i][1]==minn)
    80         {
    81             sto[++num]=i;
    82         }
    83     }
    84     sort(sto+1,sto+num+1);
    85     for(int i=1; i<=num; i++)
    86     {
    87         if(i==1)
    88             printf("%d",sto[i]);
    89         else
    90             printf(" %d",sto[i]);
    91     }
    92     printf("
    ");
    93     return 0;
    94 }
    95  

     

  • 相关阅读:
    linux下的epoll怎样高效处理百万连接
    poj 3020 Antenna Placement(二分无向图 匈牙利)
    放大的X(杭电2565)
    各种语言推断是否是手机设备
    【iOS开发-32】iOS程序真机调试须要购买调试证书怎么办?
    UIActionSheet 提示框
    关于ZEDboard
    javaScript 检測 能否够连接指定server
    陈-朱-兴- js写法【案例】:
    H5网页动画制作(页面切换、效果等)
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262742.html
Copyright © 2011-2022 走看看