【bzoj1912】[Apio2010]patrol 巡逻

1912: [Apio2010]patrol 巡逻

Time Limit: 4 Sec   Memory Limit: 64 MB
Submit: 1740   Solved: 907
[ Submit][ Status][ Discuss]

Description

Input

第一行包含两个整数 n, K(1 ≤ K ≤ 2)。接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n)。

Output

输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离。

Sample Input

8 1
1 2
3 1
3 4
5 3
7 5
8 5
5 6

Sample Output

11

HINT

10%的数据中,n ≤ 1000, K = 1; 
30%的数据中,K = 1; 
80%的数据中,每个村庄相邻的村庄数不超过 25; 
90%的数据中,每个村庄相邻的村庄数不超过 150; 
100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。

Source

[ Submit][ Status][ Discuss]



呵呵。。


K = 1时,跑最长链

K = 2时,跑完一遍最长链后把最长链的边权变成-1再跑一遍


证明什么的

不会

代码:
#include
#include
#include
#include
#include
using namespace std;

typedef long long LL;

const int INF = 2147483647;
const int maxn = 100100;

struct data{
	int to,w;
}e[maxn * 2];

vector G[maxn];
int n,p,q,a,k,cur,tote = -1,ans;
int maxx[maxn],id[maxn],fa[maxn];

inline LL getint()
{
	LL ret = 0,f = 1;
	char c = getchar();
	while (c < '0' || c > '9') 
	{
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
		ret = ret * 10 + c - '0',c = getchar();
	return ret * f;
}

inline void dfs(int u)
{
	int now1 = 0,now2 = 0;
	id[u] = u;
	for (int i = 0; i < G[u].size(); i++)
	{
		int v = e[G[u][i]].to;
		if (v == fa[u]) continue;
		fa[v] = u;
		dfs(v);
		maxx[v] += e[G[u][i]].w;
		if (maxx[v] > maxx[u])
			maxx[u] = maxx[v] , id[u] = id[v];
		if (maxx[now1] < maxx[v]) now2 = now1 , now1 = v;
		else if (maxx[now2] < maxx[v]) now2 = v;
	}
	if (maxx[now1] + maxx[now2] > cur)
		cur = maxx[now1] + maxx[now2] , p = id[now1] , q = id[now2] , a = u;
}

inline void up(int u,int to)
{
	if (u == to) return;
	for (int i = 0; i < G[u].size(); i++)
	{
		int v = e[G[u][i]].to;
		if (v != fa[u]) continue;
		e[G[u][i] ^ 1].w = e[G[u][i]].w = -1;
		up(v,to);
	}
}

int main()
{
	n = getint(); k = getint();
	for (int i = 1; i <= n - 1; i++)
	{
		int u = getint(),v = getint();
		e[++tote] = (data){v,1};
		G[u].push_back(tote);
		e[++tote] = (data){u,1};
		G[v].push_back(tote);
	}
	ans = n - 1 << 1;
	for (int i = 1; i <= k; i++)
	{
		cur = 0;
		memset(maxx,0,sizeof(maxx));
		memset(id,0,sizeof(id));
		dfs(1);
		ans -= (cur - 1);
		up(p,a); 
		up(q,a);
	}
	printf("%d",ans);
	return 0;
}

你可能感兴趣的:(动态规划,C,bzoj,树上最长链)