下午组队赛遇到的题,是在hdu上判,一直在超时,各种优化之后还是超时,最后无奈从别人博客上贴代码交,竟然还是超时,但是后来我在uva 上交,我的代码只跑了300多ms,呵呵……,然后我看那个题在hdu上最后一次ac发生在今年1月6号,我也发现还有好多和我有着同样遭遇的,果断放弃,所有下面的代码c++和java都只能在uva 上通过。(之所以要写两遍,是我寄希望于java能通过hdu诡异的测试,但是无果,而且在uva上跑的时间也比较长)。吐槽完还是说题吧。
题意:给一棵n节点的树,每条边都有权值,从根节点走到叶节点,alice希望走的路尽可能短,bob希望走的尽可能长,但是最后走过的路要在l和r之间,bob先走,没人都会做最优选择,问满足条件的最大值。
听说这是一个树形dp,但是我看方法跟我差不多,但是我没感觉是dp呢,可能还是太水。我觉得就是一个dfs,先处理出子每一个子树的状态,bob走时,节点选择子节点到叶节点最大的值,alice走时选择最小,f值为1或-1,用在比较大小的时候,1表示bob走,-1表示alice走,最后对根节点dfs返回的就是最终结果。
c++代码:
#include <string.h>
#include <stdio.h>
struct edge {
int v, l, nxt;
}e[500050];
struct node {
int mn, e;
}id[500050];
int n, l, r, no, tmp;
int dfs(int u, int f) {
// if(cost > r) return -1;
if(id[u].e == -1) {
if(id[u].mn >= l && id[u].mn <= r) {
return id[u].mn;
}
return -1;
}
int t = -1, i;
for(i = id[u].e; i != -1; i = e[i].nxt) {
id[e[i].v].mn = id[u].mn + e[i].l;
tmp = dfs(e[i].v, f * -1);
if(tmp != -1) {
if(t == -1 || (t - tmp) * f < 0)
t = tmp;
}
}
return t;
}
int main() {
int i, j, a, b, c, t;
while(~scanf("%d%d%d", &n, &l, &r)) {
memset(id, -1, sizeof(id));
no = 0;
id[0].mn = 0;
for(i = 1; i < n; i++) {
scanf("%d%d%d", &a, &b, &c);
e[no].v = b;
e[no].l = c;
e[no].nxt = id[a].e;
id[a].e = no++;
}
t = dfs(0, 1);
if(t == -1)
printf("Oh, my god!\n");
else printf("%d\n", t);
}
return 0;
}
java代码:
import java.util.Scanner;
class edge{
int v, l, nxt;
}
public class Main {
static int v[];
static edge e[];
static int n, l, r, no;
static int dfs(int u, int cost, int f) {
if(cost > r) return -1;
if(v[u] == -1) {
if(cost >= l && cost <= r) return cost;
return -1;
}
int t = -1;
for(int i = v[u]; i != -1; i = e[i].nxt) {
int tmp = dfs(e[i].v, cost + e[i].l, f * -1);
if(tmp != -1) {
if(t == -1 || (t - tmp) * f < 0)
t = tmp;
}
}
return t;
}
public static void main(String[] args) {
int i, a, b, c;
v = new int[500050];
e = new edge[500050];
if(e == null) {
System.out.println("WA");
}
Scanner in = new Scanner(System.in);
while(in.hasNext()) {
n = in.nextInt();
l = in.nextInt();
r = in.nextInt();
for(i = 0; i < n; i++)
v[i] = -1;
no = 0;
for(i = 1; i < n; i++) {
a = in.nextInt();
b = in.nextInt();
c = in.nextInt();
// System.out.println(a + " " + b + " " + c);
e[no] = new edge();
e[no].v = b;
e[no].l = c;
e[no].nxt = v[a];
// System.out.println(a + " " + b + " " + c);
v[a] = no++;
}
int t = dfs(0, 0, 1);
if(t == -1)
System.out.println("Oh, my god!");
else System.out.println(t);
}
in.close();
}
}