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

HDU 5296 Annoying problem

时间:2015-07-22 20:54:53      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=5296
实际上问题可以转化为点到一个连通子树的最短距离。。

//Hello. I‘m Peter.
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}

#define N 100010
int n, q;
struct Edge{
    int from, to, next;
    int v;
}edge[N << 1];
int head[N],numedge;
void add_edge(int from, int to, int v){
    int t= ++ numedge;
    edge[t].from = from;
    edge[t].to = to;
    edge[t].v = v;
    edge[t].next = head[from];
    head[from] = t;
}

int d[N], vto[N], rvto[N], fa[N], dep[N], dfsclo;
void get_d(int now, int father){
    vto[now] = ++dfsclo;
    rvto[dfsclo] = now;
    for(int i = head[now]; i != -1; i = edge[i].next){
        int to = edge[i].to;
        if(to == father) continue;

        fa[to] = now;
        dep[to] = dep[now] + 1;
        d[to] = d[now] + edge[i].v;
        get_d(to, now);
    }
}

int lca[N][20];
void init_lca(){
    for(int i = 1; i <= n; i++) lca[i][0] = fa[i];

    for(int j = 1; 1<<j <= n; j++){
        for(int i = 1; i <= n; i++){
            lca[i][j] = -1;
            if(lca[i][j-1] != -1){
                lca[i][j] = lca[ lca[i][j-1] ][j-1];
            }
        }
    }
}
int query_lca(int a, int b){
    if(dep[a] < dep[b]) swap(a, b);
    int log;
    for(log = 0; 1<<log <= n; log++);
    log--;
    for(int i = log; i >=0; i--){
        if(lca[a][i] != -1 && dep[ lca[a][i] ] >= dep[b]) a = lca[a][i];
    }
    if(a == b) return a;
    for(int i = log; i >=0; i--){
        if(lca[a][i] != -1 && lca[b][i] != -1 && lca[a][i] != lca[b][i]){
            a = lca[a][i];
            b = lca[b][i];
        }
    }
    return fa[a];
}

set<int>se;

int v1, v2;
void findv1v2(int v){
    if(vto[v] < *se.begin() || vto[v] > *(--se.end()) ){
        v1 = *se.begin();
        v2 = *(--se.end());
    }
    else{
        v1 = *se.lower_bound(vto[v]);
        v2 = *(--se.upper_bound(vto[v]));
    }
    v1 = rvto[v1];
    v2 = rvto[v2];
}

int main(){
    //freopen("data.txt","r",stdin);

    int T = read();
    for(int kase = 1; kase <= T; kase ++){
        printf("Case #%d:\n",kase);
        n = read(), q = read();

        for(int i =1 ; i <= n ;i++) head[i] = -1;
        numedge = 0;

        for(int i = 1; i < n; i++){
            int a, b, v;
            a = read();
            b = read();
            v = read();
            add_edge(a, b, v);
            add_edge(b, a, v);
        }

        dep[1] = 0;
        fa[1] = -1;
        dfsclo = 0;
        d[1] = 0;
        get_d(1, 0);
        init_lca();

//        for(int i = 1; i <= n; i++){
//            for(int j = 1; j <= n; j++){
//                printf("lca(%d ,%d) = %d\n",i,j,query_lca(i, j));
//            }
//        }

        int ans = 0;
        se.clear();
        for(int iq = 1; iq <= q; iq++){
            int a, v;
            a = read(), v = read();
            if(a == 1){
                if(se.find(vto[v]) == se.end()){
                    if(!se.empty()){
                        findv1v2(v);
                        ans += d[v] - d[query_lca(v, v1)] - d[query_lca(v, v2)] + d[query_lca(v1, v2)];
                    }
                    else ans = 0;
                    se.insert(vto[v]);
                }
            }
            else{
                if(se.find(vto[v]) != se.end()){
                    se.erase(vto[v]);
                    if(!se.empty()){
                        findv1v2(v);
                        ans -= d[v] - d[query_lca(v, v1)] - d[query_lca(v, v2)] + d[query_lca(v1, v2)];
                    }
                    else ans = 0;
                }
            }

            //printf("v = %d v1 = %d v2 = %d\n",v,v1 ,v2);

            printf("%d\n",ans);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 5296 Annoying problem

标签:

原文地址:http://blog.csdn.net/uestc_peterpan/article/details/47008953

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