文章标题

来源:互联网 发布:淘宝怎样卖虚拟物品 编辑:程序博客网 时间:2024/06/09 14:46

题解
比赛的时候以为这是一道动态维护树的中心,看了题解发现自己想错了,公共祖先的题目确实是少
这次学习了一下set
发现有很多使用简便的地方

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <set>#include <utility>using namespace std;#define N 111111#define iter set<int>::iteratorint par[N][20];int depth[N];int dis[N];int n,m;int p[N];int vis[N];int cnt;int dfn[N];vector<pair<int,int>>edge[N];set<int> ans;void dfs(int u,int fa){     dfn[++cnt]=u;     p[u]=cnt;     //printf("%d %d\n",u,fa);     for(int i=1;i<18;i++){ //寻找他的十八辈祖宗        par[u][i]=par[par[u][i-1]][i-1];     }     for(int i=0;i<edge[u].size();i++){        int v=edge[u][i].first;        if(fa==v) continue ;        depth[v] = depth[u] + 1;        dis[v] = dis[u] + edge[u][i].second;        par[v][0] = u;        dfs(v,u);     }}int lca(int u,int v){    if(depth[u]>depth[v]) swap(u,v);    for(int k=0;k<18;k++){        if((depth[v]-depth[u])>>k&1){            v = par[v][k];        }    }    if(v==u) return u;    for(int k=17;k>=0;k--){        if(par[u][k]!=par[v][k]){            u=par[u][k];            v=par[v][k];        }    }    return par[u][0];}int tot;int add(int u){    if (ans.empty())        return 0;    int x, y;    //寻找与u相邻的dfs序点    iter it = ans.lower_bound(p[u]);    iter itx = it;    itx--;    if (it == ans.end() || it == ans.begin()) {        it = ans.begin();        itx = ans.end();        itx--;    }    y = (*it);    x = (*itx);    y = dfn[y];    x = dfn[x];    return dis[u] - dis[lca(x, u)] - dis[lca(y, u)] + dis[lca(x, y)];}void init(){    for(int i=1;i<=n;i++){        edge[i].clear();    }    memset(vis,0,sizeof(vis));    memset(dfn,0,sizeof(dfn));    memset(p,0,sizeof(p));    memset(par,0,sizeof(par));    memset(dis,0,sizeof(dis));    memset(depth,0,sizeof(depth));    cnt=0;    ans.clear();}int main(){    int T;    int cas = 0;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        init();        int x,y,z;        for(int i=1;i<n;i++){            scanf("%d%d%d",&x,&y,&z);            edge[x].push_back(make_pair(y,z));            edge[y].push_back(make_pair(x,z));        }        /*        for(int i=1;i<=n;i++){                printf("%d :",i);                for(int j=0;j<edge[i].size();j++){                        printf("%d ",edge[i][j].first);                }                puts("");        }        */        dis[1]=0;        depth[1]=1;        dfs(1,-1);        /*        for(int i=1;i<=n;i++){                printf("%d %d %d\n",i,dis[i],par[i][0]);        }        */        int sum=0;        printf("Case #%d:\n",++cas);        for(int i=1;i<=m;i++){            scanf("%d%d",&x,&y);            int tmp;            if(x==1){                if(!vis[y]){                    vis[y]=1;                    if (ans.size() == 0) {                        ans.insert(p[y]);                    } else {                        tmp = add(y);                        ans.insert(p[y]);                        sum += tmp;                    }                }            }            else{                if(vis[y]){                    vis[y] = 0;                    ans.erase(p[y]);                    if (!ans.empty()) {                        sum -= add(y);                    }                }            }            printf("%d\n",sum);        }    }}
0 0
原创粉丝点击