Codeforces 219D Choosing Capital for Treeland 2次DP

//选择一个根使得变换最少边的方向使得能够到达所有点#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 200010;
const int MAXM = MAXN * 10;
struct Edge {
    int u,v,w;
    int next;
}edge[MAXM];
int head[MAXN],tot;

void init() {
    tot = 0;
    memset(head,-1,sizeof(head));
}

void add_edge(int u,int v,int w) {
    edge[tot].u = u;
    edge[tot].v = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int dp[MAXN],f[MAXN];
void dfs1(int u,int pre) {
    dp[u] = 0;
    for (int i = head[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v;
        if (v == pre) continue;
        dfs1(v,u);
        dp[u] += dp[v] + edge[i].w;
    }
}

void dfs2(int u,int pre) {
    for (int i = head[u] ; i != -1 ; i = edge[i].next) {
        int v = edge[i].v,w = edge[i].w;
        if (v == pre) continue;
        f[v] = f[u] - w + (1 - w);
        dfs2(v,u);
    }
}

int main() {
    int N;
    while (cin >> N) {
        init();
        for (int i = 0 ; i < N - 1 ; i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            add_edge(u,v,0);
            add_edge(v,u,1);
        }
        dfs1(1,-1);
        f[1] = dp[1];
       // cout << dp[1] << endl;
        dfs2(1,-1);
        int ans = N;
        for (int i = 1 ; i <= N ; i++) ans = min(ans,f[i]);
        cout << ans << endl;
        for (int i = 1 ; i <= N ; i++) if (f[i] == ans) printf("%d ",i);
        puts("");
    }
    return 0;
}
时间: 2024-10-29 19:07:53

Codeforces 219D Choosing Capital for Treeland 2次DP的相关文章

Codeforces 219D Choosing Capital for Treeland(树形DP)

题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正向边权值为0,反向边权值为1,那样就是各个点出发到其他点经过边所需的最少权值和. 然后对于每个点,分两个部分考虑:以这个点为根的子树.这个点往上走的部分: dp[0][u]表示以u点作为首都且以u点为根的子树部分所需反转边的数量,容易知道就等于子树内边权和 dp[1][u]表示以u点作为首都且u点向

CodeForces 219D Choosing Capital for Treeland (树形DP)

题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少.并输出所有可能作为根的点. 思路: 先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用down[i].还是那个点进行DFS,这次就要求答案了,尝试将每个点t作为根,那么以t作为根的总费用=down[t]+父亲这棵子树.down[t]已经在第一次DFS中求出,而父亲这棵子树就不是down[父亲]了,而是down[父亲]-down[t]+w(父亲,t).注:w为边权. 1 #includ

(纪念第一道完全自己想的树DP)CodeForces 219D Choosing Capital for Treeland

Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output The country Treeland consists of n cities, some pairs of them are connected with unidirectional roads. Overall

CodeForces 219D.Choosing Capital for Treeland (树形dp)

题目链接: http://codeforces.com/contest/219/problem/D 题意: 给一个n节点的有向无环图,要找一个这样的点:该点到其它n-1要逆转的道路最少,(边<u,v>,如果v要到u去,则要逆转该边方向)如果有多个这样的点,则升序输出所有 思路: 看了三篇博客,挺好的 http://blog.csdn.net/chl_3205/article/details/9284747 http://m.blog.csdn.net/qq_32570675/article/d

Codeforces 219D. Choosing Capital for Treeland (树dp)

题目链接:http://codeforces.com/contest/219/problem/D 树dp 1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio&

codeforces:219D. Choosing Capital for Treeland

题目大意:国家由n个城市以及n-1条连接不同城市的道路组成(每条道路都有正向和逆向之分),并且每个城市到另外一个城市都至少存在一条路径.现在议会要决定选一个城市作为首都.当一个城市选为首都时,需要将所有从首都到其它城市的路径上的所有边都是正向的(如果不是正向的则需要颠转道路).求这样的首都,使得需要颠转的道路数目最小. 其中2<=n<=2e5. 首先这显然是一副无向无环连通图(参考我的博客连通图的一些性质).因此从任意一个城市出发到另外一个城市都有唯一一条路径. 为了后面分析的简便,这里记选取

CF 219D Choosing Capital for Treeland 树形DP 好题

一个国家,有n座城市,编号为1~n,有n-1条有向边 如果不考虑边的有向性,这n个城市刚好构成一棵树 现在国王要在这n个城市中选择一个作为首都 要求:从首都可以到达这个国家的任何一个城市(边是有向的) 所以一个城市作为首都,可能会有若干边需要改变方向 现在问,选择哪些城市作为首都,需要改变方向的边最少. 输出最少需要改变方向的边数 输出可以作为首都的编号 树形DP 先假定城市1作为首都 令tree(i)表示以i为根的子树 dp[i]表示在tree(i)中,若以i为首都的话,需要改变的边数 第一次

树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland

题目传送门 1 /* 2 题意:求一个点为根节点,使得到其他所有点的距离最短,是有向边,反向的距离+1 3 树形DP:首先假设1为根节点,自下而上计算dp[1](根节点到其他点的距离),然后再从1开始,自上而下计算dp[v], 4 此时可以从上个节点的信息递推出来 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <vector> 10 using name

Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland dfs

D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output The country Treeland consists of n cities, some pairs of them are connected with unidirectional roads. Over