• CF219D


    /*
    *题目大意:
    *        在一棵有向树上,使任意一个点为cap,满足从这个cap能够到达所有点,
    *        条件是是你可以更改边的方向。求所有改边最小的cap.
    *解题思路:
    *        一开始直接暴力肯定是TLE,然后想到了可以从入度为0的点开始考虑,
    *        复杂度开始下降,但是明显随即数据很难搞定,接着想到了是不是
    *        重复计算次数太多了。如何减少重复计算?想到这里就没有再细想,
    *        没想到恰恰这里就是关键,先计算好随意一个cap点的改边数量。之后
    *        其它的点均可以由这个点来推算出。
    */
    View Code
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <utility>
    #include <memory.h>
    #include <stack>
    #include <queue>
    #include <deque>
    #include <time.h>
    #include <iomanip>
    
    #define pi 3.1415926535897932
    #define abs(x) ((x)>0?(x):-(x))
    #define sqr(x) ((x)*(x))
    #define sci(x) scanf("%d",&x)
    #define scd(x) scanf("%lf",&x)
    #define pri(x) printf("%d",x)
    #define prd(x) printf("%lf",x)
    #define inf 0x3f3f3f3f
    #define fi first
    #define se second
    #define tr(container, iterator) for(typeof(container.begin()) iterator=container.begin(); it != container.end(); it++)
    #define all(x) x.begin(), x.end()
    #define y0 stupid_cmath
    #define y1 very_stupid_cmath
    #define ll long long
    #define pb push_back
    #define mp make_pair
    #define rep(it,a,b) for(int it=a;it<=b;++it)
    #define _rep(it,a,b) for(int it=a;it>=b;--it)
    
    using namespace std;
    
    const int MAXN = 200005;
    const int MAXE = 200005;
    typedef struct _node
    {
        int v, w;
        int next;
    }N;
    
    vector<int> ans;
    int Min;
    N edge[2 * MAXE];
    int cntEdge, head[MAXN];
    int dp[MAXN];
    
    void init(int n)
    {
        Min = 0x7fffffff;
        cntEdge = 0;
        fill(dp, dp + n + 1, 0);
        fill(head, head + n + 1, -1);
    }
    
    void addEdge(int u, int v)
    {
        edge[cntEdge].v = v;
        edge[cntEdge].w = 0;
        edge[cntEdge].next = head[u];
        head[u] = cntEdge++;
    
        edge[cntEdge].v = u;
        edge[cntEdge].w = 1;
        edge[cntEdge].next = head[v];
        head[v] = cntEdge++;
    }
    
    void dfs1(int n, int p)
    {
        for(int f = head[n]; f != -1; f = edge[f].next)
        {
            if(edge[f].v != p)
            {
                if(edge[f].w)
                    dp[1]++;
                dfs1(edge[f].v, n);
            }
        }
    }
    
    void dfs2(int n, int p)
    {
        for(int f = head[n]; f != -1; f = edge[f].next)
        {
            if(edge[f].v != p)
            {
                if(edge[f].w == 0)
                    dp[edge[f].v] = dp[n] + 1;
                else
                    dp[edge[f].v] = dp[n] - 1;
                dfs2(edge[f].v, n);
            }
        }
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
    
        int n;
        while(scanf("%d", &n) == 1)
        {
            init(n);
            int u, v;
            for(int i = 0; i < n - 1; i++)
            {
                scanf("%d %d", &u, &v);
                addEdge(u, v);
            }
            
            dfs1(1, 1);
            dfs2(1, 1);
            
            rep(i, 1, n)
                if(dp[i] < Min)
                {
                    Min = dp[i];
                    ans.clear();
                    ans.push_back(i);
                }
                else if(dp[i] == Min)
                {
                    ans.push_back(i);
                }
    
            printf("%d\n", Min);
            sort(ans.begin(), ans.end());
            rep(i, 0, ans.size() - 1)
            {
                if(!i)
                    printf("%d", ans[i]);
                else
                    printf(" %d", ans[i]);
            }
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    sqlserver的版本号
    看了wcf后的一些疑问,请高手指导
    vs2008怎么与vss2005集成(已解决)
    下载的文件名问题[转]
    问题解答
    常见问题FAQ
    参观用友(UFIDA)产业园流水账~~
    问题解答
    Langzhi RAD Framework
    常见问题FAQ
  • 原文地址:https://www.cnblogs.com/cchun/p/2663270.html
Copyright © 2020-2023  润新知