题目描述
https://codeforces.com/contest/239/problem/E
E. WorldEater Brothers |
---|
time limit per test:2 seconds | memory limit per test 256 megabytes |
---|---|
inputstandard input | outputstandard output |
You must have heard of the two brothers dreaming of ruling the world. With all their previous plans failed, this time they decided to cooperate with each other in order to rule the world.
As you know there are n countries in the world. These countries are connected by n - 1 directed roads. If you don’t consider direction of the roads there is a unique path between every pair of countries in the world, passing through each road at most once.
Each of the brothers wants to establish his reign in some country, then it’s possible for him to control the countries that can be reached from his country using directed roads.
The brothers can rule the world if there exists at most two countries for brothers to choose (and establish their reign in these countries) so that any other country is under control of at least one of them. In order to make this possible they want to change the direction of minimum number of roads. Your task is to calculate this minimum number of roads.
Input
The first line of input contains an integer n (1 ≤ n ≤ 3000). Each of the next n - 1 lines contains two space-separated integers ai and bi (1 ≤ ai, bi ≤ n; ai ≠ bi) saying there is a road from country ai to country bi.
Consider that countries are numbered from 1 to n. It’s guaranteed that if you don’t consider direction of the roads there is a unique path between every pair of countries in the world, passing through each road at most once.
Output
In the only line of output print the minimum number of roads that their direction should be changed so that the brothers will be able to rule the world.
input input
4 5
2 1 2 1
3 1 2 3
4 1 4 3
4 5
output output
1 0
排版不好看,不知道别人的这么写的。。
一棵有向树,改变其中一些树边的方向,可以选取出这样两个结点u1,u2,使得任意结点v,存在u1->v,或者u2->v,求最少改变几条边的方向
题目分析
如果需要修改边的方向,必然至少存在一个结点它的入度为0,或出度为0(想想就明白了),将树分为至少两个连通块。
那么我们就可以枚举每一条边(u->v),将树分为两个弱连通块,分别计算以u,v为根结点的树的反向边数量和正向边数量的较小值dp[u]、dp[v],则least_cost=min{ min{dp[u]}+min{dp[v]} }
正向边的数量可以由反向边的数量计算出,只需在遍历子树时,记录反向边与正向边的差值dif,再由反向边的数量cost,减去dif便可,然后更新dp[u]=min(cost,cost-dif) ------若为正向边多,则该弱联通块的根节点为u,若反向边多,则根节点为该弱联通块中的某一个结点
代码参考
/*
* @Author: CHAOS_ORDER
* @Date: 2019-10-05 12:58:27
* @LastEditors: CHAOS_ORDER
* @LastEditTime: 2019-10-05 16:23:27
* @Description: World Eater Brothers https://codeforces.com/problemset/problem/239/E
* @Status: Accepted 280ms
*/
#include <functional>
#include <algorithm>
#i