正文
T - zxa and leaf HDU - 5682 二分+dfs
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
T - zxa and leaf
HDU - 5682
题目大意是:给你一颗树,这棵树有些节点已经设置了它的美丽值,然后剩下一些节点需要我们设置美丽值。
一条边的丑陋程度等于被定义为由这个边缘连接的两个节点之间的美丽水平的绝对差异
一棵树的丑陋程度则是边的丑陋程度的最大值。
这个题目应该是二分这个丑陋值。
然后dfs来判断这个丑陋值是不是合理。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ;
vector<int>G[maxn];
ll lc[maxn], rc[maxn], el[maxn], er[maxn]; bool dfs(int u,int pre,int x)
{
//printf("u=%d pre=%d x=%d\n", u, pre, x);
int flag = ;
for(int i=;i<G[u].size();i++)
{
int v = G[u][i];
if (v == pre) continue;
if (lc[v] == && rc[v] == ) {
lc[v] = max(1ll * , lc[u] - x);
rc[v] = rc[u] + x;
}
else {
ll val = lc[v];
if ((val <= rc[u] && val >= lc[u]))
{
rc[u] = min(rc[u], val + x);
lc[u] = max(val - x, lc[u]);
}
else if (abs(val - lc[u]) <= x || abs(val - rc[u]) <= x)
{
if (val >= rc[u]) lc[u] = max(lc[u], val - x);
if (val <= lc[u]) rc[u] = min(rc[u], val + x);
if (lc[u] > rc[u]) return false;
}
else return false;
}
//printf("lc[%d]=%lld rc[%d]=%lld\n", v, lc[v], v, rc[v]);
if (dfs(v, u, x) == ) flag = ;
}
return flag;
} int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, k;
memset(el, , sizeof(el));
memset(er, , sizeof(er));
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++) G[i].clear();
for (int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
int mark = ;
for (int i = ; i <= k; i++) {
int u, w;
scanf("%d%d", &u, &w);
mark = u;
el[u] = er[u] = w;
}
//printf("mark=%d\n", mark);
int l = , r = 1e9, ans = ;
while(l<=r)
{
memcpy(lc, el, sizeof(el));
memcpy(rc, er, sizeof(er));
int mid = (l + r) >> ;
if (dfs(mark,-,mid)) ans = mid, r = mid - ;
else l = mid + ;
//printf("l=%d r=%d mid=%d ans=%d\n\n", l, r, mid, ans);
}
printf("%d\n", ans);
}
}
/*
2
10 4
7 2
1 5
10 2
1 9
5 7
1 8
3 5
4 7
6 8
9 39
6 9
2 26
4 10
*/