zoukankan      html  css  js  c++  java
  • 2286: [Sdoi2011]消耗战

    2286: [Sdoi2011]消耗战

    链接

    分析

      虚树练习题。

      构建虚树,在虚树上DP。

       

      跟着gxb学虚-tree。。。

    代码

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <cmath>
      6 #include <cctype>
      7 
      8 using namespace std;
      9 
     10 const int N = 250100; 
     11 const int INF = 1e9;
     12 
     13 int head[N<<1],nxt[N<<1],to[N<<1],w[N<<1],TotE;
     14 int deth[N],val[N],siz[N],dfn[N],fa[N],son[N],bel[N],sk[N<<1],top,Time_index;
     15 int A[N];
     16 
     17 inline int read() {
     18     int x = 0,f = 1;char ch =getchar();
     19     for (; !isdigit(ch); ch=getchar()) if (ch=='-') f=-1;
     20     for (; isdigit(ch); ch=getchar()) x = x*10+ch-'0';
     21     return x * f;
     22 }
     23 bool cmp(const int &a,const int &b) {
     24     return dfn[a] < dfn[b];
     25 }
     26 void Add_edge(int u,int v,int c) {
     27     ++TotE;to[TotE] = v;w[TotE] = c;nxt[TotE] = head[u];head[u] = TotE;
     28     ++TotE;to[TotE] = u;w[TotE] = c;nxt[TotE] = head[v];head[v] = TotE;
     29 }
     30 void add_edge(int u,int v) {
     31     ++TotE;to[TotE] = v;nxt[TotE] = head[u];head[u] = TotE;
     32 }
     33 void dfs1(int u,int mn) {
     34     val[u] = mn;
     35     siz[u] = 1;
     36     for (int i=head[u]; i; i=nxt[i]) {
     37         int v = to[i];
     38         if (v==fa[u]) continue;        
     39         fa[v] = u;
     40         deth[v] = deth[u] + 1;
     41         dfs1(v,min(w[i],mn));
     42         siz[u] += siz[v];
     43         if (!son[u] || siz[v] > siz[son[u]]) son[u] = v;
     44     }
     45 }
     46 void dfs2(int u,int top) {
     47     bel[u] = top;
     48     dfn[u] = ++Time_index;
     49     if (!son[u]) return;
     50     dfs2(son[u],top);
     51     for (int i=head[u]; i; i=nxt[i]) {
     52         int v = to[i];
     53         if (v==fa[u] || v==son[u]) continue;
     54         dfs2(v,v);
     55     }
     56 }
     57 int Lca(int u,int v) {
     58     while (bel[u] != bel[v]) {
     59         if (deth[bel[u]] < deth[bel[v]]) swap(u,v);
     60         u = fa[bel[u]];
     61     }
     62     if (deth[u] < deth[v]) return u;
     63     return v;
     64 }
     65 void Insert(int p) {
     66     int x = sk[top];
     67     if (x==1) {sk[++top] = p;return ;}
     68     int lca = Lca(p,x);
     69     if (lca == x) return; // 此题构建虚树不同的是,若x==lca,不加入p。 
     70     while (lca != x) {
     71         int y = sk[--top];
     72         if (dfn[y] < dfn[lca]) {
     73             add_edge(lca,x);
     74             sk[++top] = lca;
     75             break;
     76         }
     77         add_edge(y,x);
     78         x = sk[top];
     79     }
     80     sk[++top] = p;
     81 }
     82 long long DP(int u) {
     83     if (!head[u]) return val[u];
     84     long long ans = 0;
     85     for (int i=head[u]; i; i=nxt[i]) ans += DP(to[i]);
     86     head[u] = 0;
     87     return min(ans,(long long)val[u]);    
     88 }
     89 int main() {
     90     int n = read();
     91     for (int i=1; i<n; ++i) {
     92         int u = read(),v = read(),w = read();
     93         Add_edge(u,v,w);
     94     }
     95     deth[1] = 1;
     96     dfs1(1,INF);
     97     dfs2(1,1);
     98     TotE = 0;
     99     memset(head,0,sizeof(head));
    100     
    101     int m = read();
    102     while (m--) {
    103         TotE = 0;sk[top = 1] = 1;
    104         
    105         int k = read();
    106         for (int i=1; i<=k; ++i) A[i] = read();
    107         sort(A+1,A+k+1,cmp);
    108         for (int i=1; i<=k; ++i) Insert(A[i]);
    109         while (--top) add_edge(sk[top],sk[top+1]);
    110         
    111         long long ans = 0;
    112         for (int i=head[1]; i; i=nxt[i]) ans += DP(to[i]); // 单独处理1的情况,否则val[1]设为很大的longlong数,INF不够。 
    113         printf("%lld
    ",ans);
    114         head[1] = 0;        
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    工欲善其事,必先利其器
    年度总结
    人脸解锁从底层到上层(一)
    Hexo NexT 主题添加评论和文章阅读量
    摄影历程-第一章
    西藏之旅
    软件测试和评估
    WordCount优化
    WordCount编码与测试
    值得深入思考的五个问题
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9180201.html
Copyright © 2011-2022 走看看