• CodeForces


    http://codeforces.com/problemset/problem/219/D

    题意:
    给出有向五环图,现在要找一个点,使得它到其余所有点的需要逆转的边最少。即如果u—>v,那么v到u需要逆转边。

    思路:

    树形dp啦,需要逆转的边可以来自子树,也可以来自父亲结点。

    分两次dfs即可,一次子树,一次父亲,熟悉的套路啊。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,ll> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn=2*1e5+5;
    17 
    18 int n;
    19 int tot;
    20 int head[maxn];
    21 int d[maxn];
    22 int r_d[maxn];
    23 int ans;
    24 
    25 struct node
    26 {
    27     int to;
    28     int next;
    29     int flag;
    30 }e[2*maxn];
    31 
    32 void addEdge(int u, int v, int x)
    33 {
    34     e[tot].to=v;
    35     e[tot].flag=x;
    36     e[tot].next=head[u];
    37     head[u]=tot++;
    38 }
    39 
    40 void dfs(int u, int fa)  //子树方向
    41 {
    42     d[u]=0;
    43     for(int i=head[u];i!=-1;i=e[i].next)
    44     {
    45         int v=e[i].to;
    46         if(v==fa)  continue;
    47         dfs(v,u);
    48         d[u]+=d[v]+e[i].flag;
    49     }
    50 }
    51 
    52 void dfs2(int u, int fa)  //父亲方向
    53 {
    54     for(int i=head[u];i!=-1;i=e[i].next)
    55     {
    56         int v=e[i].to;
    57         if(v==fa)  continue;
    58         r_d[v]=r_d[u]+d[u]-d[v]+(e[i].flag?0:1)-e[i].flag;
    59         dfs2(v,u);
    60     }
    61 }
    62 
    63 int main()
    64 {
    65     //freopen("in.txt","r",stdin);
    66     while(~scanf("%d",&n))
    67     {
    68         tot=0;
    69         memset(head,-1,sizeof(head));
    70         for(int i=1;i<n;i++)
    71         {
    72             int u,v;
    73             scanf("%d%d",&u,&v);
    74             addEdge(u,v,0);
    75             addEdge(v,u,1);
    76         }
    77         ans=INF;
    78         dfs(1,-1);
    79         dfs2(1,-1);
    80 
    81         for(int i=1;i<=n;i++)  ans=min(ans,d[i]+r_d[i]);
    82 
    83         printf("%d
    ",ans);
    84 
    85         bool first=true;
    86         for(int i=1;i<=n;i++)
    87         {
    88             if(d[i]+r_d[i]==ans)
    89             {
    90                 if(first)  {first=false;}
    91                 else printf(" ");
    92                 printf("%d",i);
    93             }
    94         }
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    linux下通过命令行重启服务,查看id,更改tv密码
    windows渗透相关、hideadmin工具隐藏用户账号、添加隐藏用户
    windows服务隐藏 以及进程隐藏
    nat32 winh命令远程执行难点
    anydesk命令行使用
    html页面,能用鼠标滚轮滑动,但是不能触屏滑动
    Java 全局统一异常捕获
    git 常用操作
    vue v-for强制刷新
    flutter-TextField垂直居中
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7344739.html
Copyright © 2020-2023  润新知