zoukankan      html  css  js  c++  java
  • SPOJ

    题目传送门

    题意:有一棵数,每个节点有颜色,黑色或者白色,树边有边权,现在有2个操作,1修改某个点的颜色, 2询问2个白点的之前的路径权值最大和是多少。

    题解:

    边分治思路。

    1.重构图。 因为边分治在菊花图的情况下情况不理想,所以需要先把图重新构建一下,是每个点的度数不超过3。

    2.找在新图里面  一条边使得 断开这条边的情况下,左右2新树使得较大的那个子树是所有情况下的最小值。

    3.开2个优先队列去维护左边新树的白点的最大值, 右边新树的所有白点的最大值, 然后 左边白点+右边白点+中间边就是最大值。

    4.对于2个新图都执行 2-3的操作。

    代码:

      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]; int to[N<<1];
     22     int ct[N<<1]; int nt[N<<1];
     23     int tot;
     24     void init(){
     25         tot = 0;
     26         memset(head, -1, sizeof(head));
     27         return ;
     28     };
     29     void add(int u, int v, int val){
     30         to[tot] = v; ct[tot] = val;
     31         nt[tot] = head[u]; head[u] = tot++;
     32         return ;
     33     }
     34 }e[2];
     35 int n, u, v, w;
     36 void rebuild(int o, int u){
     37     int ff = 0;
     38     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
     39         v = e[0].to[i], w = e[0].ct[i];
     40         if(v == o) continue;
     41         if(!ff){
     42             e[1].add(u, v, w);
     43             e[1].add(v, u, w);
     44             ff = u;
     45         }
     46         else {
     47             ++n;
     48             e[1].add(ff, n, 0);
     49             e[1].add(n, ff, 0);
     50             e[1].add(v, n, w);
     51             e[1].add(n, v, w);
     52             ff = n;
     53         }
     54         rebuild(u, v);
     55     }
     56     return ;
     57 }
     58 vector<pll> vc[N];
     59 priority_queue<pll> pq[N<<2][2]; int wedge[N<<2];
     60 int white[N], sz[N];
     61 int cut[N<<1];
     62 int id, maxnum = 0;
     63 void get_edge(int o, int u, int num){
     64     sz[u] = 1;
     65     int tmp = 0;
     66     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     67         int v = e[1].to[i];
     68         if(v == o || cut[i>>1]) continue;
     69         get_edge(u, v, num);
     70         sz[u] += sz[v];
     71         tmp = max(num-sz[v], sz[v]);
     72         if(tmp < maxnum){
     73             id = i;
     74             maxnum = tmp;
     75         }
     76     }
     77     return ;
     78 }
     79 int k = 0, op;
     80 void dfs(int o, int u, int w){
     81     sz[u] = 1;
     82     if(white[u]){
     83         pq[k][op].push(pll(w, u));
     84         if(op == 0) vc[u].push_back(pll(-k, w));
     85         else vc[u].push_back(pll(k, w));
     86     }
     87     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     88         int v = e[1].to[i];
     89         if(v == o || cut[i>>1]) continue;
     90         dfs(u, v, w+e[1].ct[i]);
     91         sz[u] += sz[v];
     92     }
     93     return ;
     94 }
     95 int ans[N], lch[N], rch[N];
     96 void update(int k){
     97     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
     98     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
     99     if(pq[k][0].empty() || pq[k][1].empty())
    100         ans[k] = 0;
    101     else {
    102         int val1 = pq[k][0].top().fi, val2 = pq[k][1].top().fi;
    103         int sum = val1 + val2 + wedge[k];
    104         ans[k] = max(sum, 0);
    105     }
    106     if(lch[k]) ans[k] = max(ans[k], ans[lch[k]]);
    107     if(rch[k]) ans[k] = max(ans[k], ans[rch[k]]);
    108     return ;
    109 }
    110 int solve(int u, int num){
    111     if(num == 1) return 0;
    112     maxnum = inf;
    113     get_edge(0, u, num);
    114     int now = ++k, nid = id;
    115     cut[nid >> 1] = 1;
    116     wedge[k] = e[1].ct[nid];
    117     op = 0;
    118     dfs(0, e[1].to[nid], 0);
    119     op = 1;
    120     dfs(0, e[1].to[nid^1], 0);
    121     lch[now] = solve(e[1].to[nid], sz[e[1].to[nid]]);
    122     rch[now] = solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
    123     update(now);
    124     return now;
    125 }
    126 void setWhite(int u){
    127     for(int i = vc[u].size()-1; i >= 0; --i){
    128         pll tmp = vc[u][i];
    129         int k = tmp.fi, ct = tmp.se;
    130         if(k < 0) pq[-k][0].push(pll(ct, u));
    131         else pq[k][1].push(pll(ct, u));
    132         update(abs(k));
    133     }
    134     return ;
    135 }
    136 void setBlack(int u){
    137     for(int i = vc[u].size()-1; i >= 0; --i)
    138         update(abs(vc[u][i].fi));
    139     return ;
    140 }
    141 int main(){
    142     scanf("%d", &n);
    143     int white_num = n, q;
    144     char op[10];
    145     e[0].init(); e[1].init();
    146     for(int i = 1; i < n; i++){
    147         scanf("%d%d%d", &u, &v, &w);
    148         e[0].add(u, v, w);
    149         e[0].add(v, u, w);
    150         white[i] = 1;
    151     }
    152     white[n] = 1;
    153     rebuild(0, 1);
    154     solve(1, n);
    155     scanf("%d", &q);
    156     while(q--){
    157         scanf("%s", op);
    158         if(op[0] == 'A') {
    159             if(white_num == 0) puts("They have disappeared.");
    160             else if(white_num == 1) puts("0");
    161             else printf("%d
    ", ans[1]);
    162         }
    163         else {
    164             scanf("%d", &u);
    165             white[u] ^= 1;
    166             if(white[u])
    167                 setWhite(u), ++white_num;
    168             else
    169                 setBlack(u), --white_num;
    170         }
    171     }
    172     return 0;
    173 }
    View Code
      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]; int to[N<<1];
     22     int ct[N<<1]; int nt[N<<1];
     23     int tot;
     24     void init(){
     25         tot = 0;
     26         memset(head, -1, sizeof(head));
     27         return ;
     28     };
     29     void add(int u, int v, int val){
     30         to[tot] = v; ct[tot] = val;
     31         nt[tot] = head[u]; head[u] = tot++;
     32         return ;
     33     }
     34 }e[2];
     35 int n, u, v, w;
     36 void rebuild(int o, int u){
     37     int ff = 0;
     38     for(int i = e[0].head[u]; ~i; i = e[0].nt[i]){
     39         v = e[0].to[i], w = e[0].ct[i];
     40         if(v == o) continue;
     41         if(!ff){
     42             e[1].add(u, v, w);
     43             e[1].add(v, u, w);
     44             ff = u;
     45         }
     46         else {
     47             ++n;
     48             e[1].add(ff, n, 0);
     49             e[1].add(n, ff, 0);
     50             e[1].add(v, n, w);
     51             e[1].add(n, v, w);
     52             ff = n;
     53         }
     54         rebuild(u, v);
     55     }
     56     return ;
     57 }
     58 vector<pll> vc[N];
     59 priority_queue<pll> pq[N<<2][2]; int wedge[N<<2];
     60 int white[N], sz[N];
     61 int cut[N<<1];
     62 int id, maxnum = 0;
     63 void get_edge(int o, int u, int num){
     64     sz[u] = 1;
     65     int tmp = 0;
     66     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     67         int v = e[1].to[i];
     68         if(v == o || cut[i>>1]) continue;
     69         get_edge(u, v, num);
     70         sz[u] += sz[v];
     71         tmp = max(num-sz[v], sz[v]);
     72         if(tmp < maxnum){
     73             id = i;
     74             maxnum = tmp;
     75         }
     76     }
     77     return ;
     78 }
     79 int k = 0, op;
     80 void dfs(int o, int u, int w){
     81     sz[u] = 1;
     82     if(white[u]){
     83         pq[k][op].push(pll(w, u));
     84         if(op == 0) vc[u].push_back(pll(-k, w));
     85         else vc[u].push_back(pll(k, w));
     86     }
     87     for(int i = e[1].head[u]; ~i; i = e[1].nt[i]){
     88         int v = e[1].to[i];
     89         if(v == o || cut[i>>1]) continue;
     90         dfs(u, v, w+e[1].ct[i]);
     91         sz[u] += sz[v];
     92     }
     93     return ;
     94 }
     95 int ans[N], lch[N], rch[N];
     96 void update(int k){
     97     while(!pq[k][0].empty() && !white[pq[k][0].top().se]) pq[k][0].pop();
     98     while(!pq[k][1].empty() && !white[pq[k][1].top().se]) pq[k][1].pop();
     99     if(pq[k][0].empty() || pq[k][1].empty())
    100         ans[k] = 0;
    101     else {
    102         int val1 = pq[k][0].top().fi, val2 = pq[k][1].top().fi;
    103         int sum = val1 + val2 + wedge[k];
    104         ans[k] = max(sum, 0);
    105     }
    106     if(lch[k]) ans[k] = max(ans[k], ans[lch[k]]);
    107     if(rch[k]) ans[k] = max(ans[k], ans[rch[k]]);
    108     return ;
    109 }
    110 int solve(int u, int num){
    111     if(num == 1) return 0;
    112     maxnum = inf;
    113     get_edge(0, u, num);
    114     int now = ++k, nid = id;
    115     cut[nid >> 1] = 1;
    116     wedge[k] = e[1].ct[nid];
    117     op = 0;
    118     dfs(0, e[1].to[nid], 0);
    119     op = 1;
    120     dfs(0, e[1].to[nid^1], 0);
    121     lch[now] = solve(e[1].to[nid], sz[e[1].to[nid]]);
    122     rch[now] = solve(e[1].to[nid^1], sz[e[1].to[nid^1]]);
    123     update(now);
    124     return now;
    125 }
    126 void setWhite(int u){
    127     for(int i = vc[u].size()-1; i >= 0; --i){
    128         pll tmp = vc[u][i];
    129         int k = tmp.fi, ct = tmp.se;
    130         if(k < 0) pq[-k][0].push(pll(ct, u));
    131         else pq[k][1].push(pll(ct, u));
    132         update(abs(k));
    133     }
    134     return ;
    135 }
    136 void setBlack(int u){
    137     for(int i = vc[u].size()-1; i >= 0; --i)
    138         update(abs(vc[u][i].fi));
    139     return ;
    140 }
    141 int main(){
    142     scanf("%d", &n);
    143     int white_num = n, q;
    144     char op[10];
    145     e[0].init(); e[1].init();
    146     for(int i = 1; i < n; i++){
    147         scanf("%d%d%d", &u, &v, &w);
    148         e[0].add(u, v, w);
    149         e[0].add(v, u, w);
    150         white[i] = 1;
    151     }
    152     white[n] = 1;
    153     rebuild(0, 1);
    154     solve(1, n);
    155     scanf("%d", &q);
    156     while(q--){
    157         scanf("%s", op);
    158         if(op[0] == 'A') {
    159             if(white_num == 0) puts("They have disappeared.");
    160             else if(white_num == 1) puts("0");
    161             else printf("%d
    ", ans[1]);
    162         }
    163         else {
    164             scanf("%d", &u);
    165             white[u] ^= 1;
    166             if(white[u])
    167                 setWhite(u), ++white_num;
    168             else
    169                 setBlack(u), --white_num;
    170         }
    171     }
    172     return 0;
    173 }
    View Code
  • 相关阅读:
    SQl 语句(常见) 新建,删除,修改表结构
    3步把您的java程序转换为webservice
    JSP标签中不要省略引号
    图文并茂——使用xfire编写webservice,并通过C#调用
    Java取随机数
    JAVA获取文件本身所在的磁盘位置
    XFire 入门
    mysql复制表和表结构
    遍历HashMap及获取所有的Key值
    MyEclipse+struts+Hibernate配置开发
  • 原文地址:https://www.cnblogs.com/MingSD/p/9879463.html
Copyright © 2011-2022 走看看