码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 238C World Eater Brothers

时间:2015-03-15 21:15:23      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

题意:

  输入n,表示有n个城市,分别为1~n,输入n-1组a,b,表示从a能走到b,求最少改变多少条路使得从其中的两个城市出发能走完所有的城市。

(http://blog.csdn.net/metalseed/article/details/8045038%20 与建树有关的东西 )

 

解题思路:

建立一棵树,断开一条边,把树分成两部分,计算这两部分的最小改变量

那么就变成了子树最小改变量的问题

dp[i]表示以i为根的子树需要的改变量

如果以root为起点,那么cost[root] = dp[root]   如果以这棵子树上的任意一个u为起点

则  cost[u] = dp[root] + u-root需要改变的量 - root-u需要改变的量

要使cost[u]最小,则(u-root需改变+root-u需改变)值最小

 

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 const int N = 1e5 + 10; //1e5是10的5次方 
 8 struct Edge
 9 {
10     int from, to, dis, nex;
11 }edge[N<<1];
12 int head[N], edgenum; 
13 void add(int u, int v, int d)
14 {
15     Edge E = { u, v, d, head[u] };
16     edge[edgenum] = E;
17     head[u] = edgenum++;
18 }
19 int dp[N];
20 int n, mx;
21 void dfs(int u, int fa, int val)
22 {
23     dp[u] = 0;
24     for (int i = head[u]; ~i; i = edge[i].nex)//~i表示取反,其实就是非零 
25     {
26         int v = edge[i].to;
27         if (v == fa)continue;
28         dfs(v, u, val-edge[i].dis); 
29         dp[u] += dp[v] + (edge[i].dis!=1);//如果括号里的成立则加1,否则加0 
30     }
31     mx = max(mx, val);
32 }
33 int main()
34 {
35     while (cin >> n)
36     {
37         if (n == 1){ puts("0"); continue; }//puts 输出并换行 头文件cstdio 
38         memset(head, -1, sizeof head);
39         edgenum = 0;
40         for (int i = 1, u, v; i < n; i++)
41         {
42             scanf("%d %d", &u, &v);
43             add(u, v, 1);
44             add(v, u, -1);  
45         }
46         int ans = 1 << 30;
47         for (int i = 0, u, v; i < edgenum; i += 2)
48         {
49             u = edge[i].from; v = edge[i].to;
50             mx = -(1<<30);
51             dfs(u, v, 0);
52             int tmp = dp[u] - mx;
53             mx = -(1<<30);
54             dfs(v, u, 0);
55             tmp += dp[v] - mx;
56             ans = min(ans, tmp);
57         }
58         printf("%d\n", ans);
59     }
60     return 0;
61 }
View Code

 

CodeForces 238C World Eater Brothers

标签:

原文地址:http://www.cnblogs.com/yscc/p/4338574.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!