20150127
BZOJ2815 [ZJOI2012]灾难

BZOJ3251 树上三角形

laekov posted @ 2015年1月27日 23:00 in 未分类 with tags DS bzoj , 527 阅读

原来在win下也有敲回车的bug。开心。

 

这题坑啊。暴力还是很好想的,如果个数超过几十个的话就肯定有解了。比较坑的是两边之和大于第三边,边权231-1然后加起来就超过int的范围了。连WA若干次再见。

 

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct edge {
	int t;
	edge *next;
};

const int maxn = 100009;
const int maxc = 88;

int n, m, v[maxn], d[maxn], fa[maxn], c[maxc];
edge *head[maxn], elst[maxn << 1], *ep(elst);

void bfs() {
	static int q[maxn];
	int hd(0), tl(1);
	q[0] = 1;
	memset(d, 0, sizeof(d));
	d[1] = 1;
	while (hd < tl) {
		int p(q[hd ++]);
		for (edge* e = head[p]; e; e = e-> next) 
			if (!d[e-> t]) {
				d[e-> t] = d[p] + 1;
				fa[e-> t] = p;
				q[tl ++] = e-> t;
			}
	}
}

bool qry(int x, int y) {
	int t(0);
	while (t < 60 && x != y) {
		if (d[x] > d[y]) {
			c[t ++] = v[x];
			x = fa[x];
		}
		else {
			c[t ++] = v[y];
			y = fa[y];
		}
	}
	if (x == y)
		c[t ++] = v[x];
	else
		return 1;
	sort(c, c + t);
	for (int i = 2; i < t; ++ i)
		if (c[i] - c[i - 1] < c[i - 2])
			return 1;
	return 0;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++ i)
		scanf("%d", v + i);
	for (int i = 1; i < n; ++ i) {
		int u, v;
		scanf("%d%d", &u, &v);
		ep-> t = v;
		ep-> next = head[u];
		head[u] = ep ++;
		ep-> t = u;
		ep-> next = head[v];
		head[v] = ep ++;
	}
	bfs();
	while (m --) {
		int t, x, y;
		scanf("%d%d%d", &t, &x, &y);
		if (t == 0)
			puts(qry(x, y) ? "Y" : "N");
		else 
			v[x] = y;
	}
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter