zoukankan      html  css  js  c++  java
  • SPOJ

    题目传送门

    题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少。

    题解:

    这里用的还是边分治的方法。

    把所有东西都抠出来, 然后每次询问的时候都访问每幅分割图的另外一侧。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define lch(x) tr[x].son[0]
     12 #define rch(x) tr[x].son[1]
     13 #define max3(a,b,c) max(a,max(b,c))
     14 #define min3(a,b,c) min(a,min(b,c))
     15 typedef pair<int,int> pll;
     16 const int inf = 0x3f3f3f3f;
     17 const LL INF = 0x3f3f3f3f3f3f3f3f;
     18 const LL mod =  (int)1e9+7;
     19 const int N = 2e5 + 100;
     20 struct Node{
     21     int head[N], to[N<<1], nt[N<<1], ct[N<<1];
     22     int tot;
     23     void init(){
     24         memset(head, -1, sizeof(head));
     25         tot = 0;
     26     }
     27     void add(int u, int v, int cost){
     28         ct[tot] = cost;
     29         to[tot] = v;
     30         nt[tot] = head[u];
     31         head[u] = tot++;
     32     }
     33 }e[2];
     34 int n, m, white[N], cut[N<<1];
     35 void rebuild(int o, int u){
     36     int ff = 0;
     37     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
     38         int v = e[0].to[i];
     39         if(o == v) continue;
     40         if(!ff){
     41             e[1].add(u, v, 1);
     42             e[1].add(v, u, 1);
     43             ff = u;
     44         }
     45         else {
     46             ++n;
     47             e[1].add(ff, n, 0); e[1].add(n, ff, 0);
     48             e[1].add(n, v, 1); e[1].add(v, n, 1);
     49             ff = n;
     50         }
     51         rebuild(u, v);
     52     }
     53 }
     54 int sz[N], minval, id;
     55 void get_edge(int o, int u, int num){
     56     sz[u] = 1;
     57     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     58         int v = e[1].to[i];
     59         if(v == o || cut[i>>1]) continue;
     60         get_edge(u, v, num);
     61         sz[u] += sz[v];
     62         int tmp = max(sz[v], num - sz[v]);
     63         if(tmp < minval){
     64             minval = tmp;
     65             id = i;
     66         }
     67     }
     68 }
     69 int k = 0, op;
     70 vector<pll> vc[N];
     71 priority_queue<pll, vector<pll>, greater<pll> > pq[N<<2][2];
     72 int wedge[N<<2];
     73 int mm;
     74 void dfs2(int o, int u, int w){
     75     vc[u].pb(pll(k*op, w));
     76     sz[u] = 1;
     77     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     78         int v = e[1].to[i];
     79         if(v == o || cut[i>>1]) continue;
     80         dfs2(u, v, w + e[1].ct[i]);
     81         sz[u] += sz[v];
     82     }
     83 }
     84 void solve(int u, int num){
     85     if(num <= 1) return ;
     86     minval = inf;
     87     get_edge(0, u, num);
     88     int nid = id;
     89     cut[nid>>1] = 1;
     90     ++k;
     91     op = 1;
     92     dfs2(0, e[1].to[nid], 0);
     93     op = -1;
     94     dfs2(0, e[1].to[nid^1], 0);
     95     wedge[k] = e[1].ct[nid];
     96     solve(e[1].to[nid], sz[e[1].to[nid]]);
     97     solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
     98 }
     99 void Update(int k){
    100     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
    101     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
    102 }
    103 void setwhite(int u){
    104     for(int i = 0; i < vc[u].size(); i++){
    105         int k = vc[u][i].fi, w = vc[u][i].se;
    106         if(k < 0) pq[-k][0].push(pll(w,u));
    107         else pq[k][1].push(pll(w,u));
    108         Update(abs(k));
    109     }
    110 }
    111 void setblack(int u){
    112     for(int i = 0; i < vc[u].size(); i++){
    113         int k = vc[u][i].fi;
    114         Update(abs(k));
    115     }
    116 }
    117 int Find(int u){
    118     int ret = inf;
    119     for(int i = 0; i < vc[u].size(); i++){
    120         int k = vc[u][i].fi, w = vc[u][i].se;
    121         if(k < 0 && !pq[-k][1].empty())
    122                 ret = min(ret, w+wedge[-k]+pq[-k][1].top().fi);
    123         if(k > 0 && !pq[k][0].empty())
    124             ret = min(ret, w+wedge[k]+pq[k][0].top().fi);
    125     }
    126     return ret;
    127 }
    128 int main(){
    129     e[0].init(); e[1].init();
    130     scanf("%d", &n);
    131     int u, v;
    132     for(int i = 1; i < n; i++){
    133         scanf("%d%d", &u, &v);
    134         e[0].add(u, v, 1); e[0].add(v, u, 1);
    135     }
    136     memset(white, 0, sizeof(white));
    137     rebuild(0, 1);
    138     solve(1, n);
    139     int num = 0, op;
    140     scanf("%d", &m);
    141     while(m--){
    142         scanf("%d%d", &op, &v);
    143         if(op == 0){
    144             white[v] ^= 1;
    145             if(white[v]){
    146                 setwhite(v);
    147                 num++;
    148             }
    149             else {
    150                 setblack(v);
    151                 num--;
    152             }
    153         }
    154         else {
    155             if(num == 0) puts("-1");
    156             else if(white[v]) puts("0");
    157             else {
    158                 printf("%d
    ", Find(v));
    159             }
    160         }
    161     }
    162     return 0;
    163 }
    View Code
  • 相关阅读:
    powershell命令大全
    Android USB Connections Explained: MTP, PTP, and USB Mass Storage
    安装Windows Metasploit Framework
    Sublime Text2 jedi插件离线安装
    MySQL下载安装配置和Navicat for MySQL的安装配置
    Sublime中文编码问题
    Flask入门之结构重组(瘦身)-第13讲笔记
    Flask入门之SQLAlchemy配置与数据库连接
    Flask入门之flask-wtf表单处理
    Total Command使用笔记
  • 原文地址:https://www.cnblogs.com/MingSD/p/9916567.html
Copyright © 2011-2022 走看看