• uoj#87. mx的仙人掌


      1 //Achen
      2 #include<bits/stdc++.h>
      3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
      4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
      5 #define Formylove return 0
      6 const int N=2e6+7,mod=571111;
      7 typedef long long LL;
      8 typedef double db;
      9 using namespace std;
     10 int n,m,Q;
     11 
     12 template<typename T> void read(T &x) {
     13     char ch=getchar(); T f=1; x=0;
     14     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     15     if(ch=='-') f=-1,ch=getchar();
     16     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     17 }
     18 
     19 LL ans,Hdis[N];
     20 int isnode[N];
     21 struct VMtree{
     22     int ecnt,fir[N],nxt[N],to[N]; LL val[N];
     23     void add(int u,int v,LL w) {
     24         nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
     25         nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
     26         //printf("%d %d %lld
    ",u,v,w);
     27     }
     28     LL f[N];
     29     int que[N];
     30     void dfs(int x,int fa) {
     31         f[x]=0;
     32         for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa)
     33             dfs(to[i],x);
     34         if(x<=n) {
     35             for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     36                 int y=to[i];
     37                 ans=max(ans,f[y]+val[i]+f[x]); f[x]=max(f[x],f[y]+val[i]);
     38             }
     39         }
     40         else {
     41             int ql=1,qr=0;
     42             for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     43                 int y=to[i];
     44                 f[x]=max(f[x],f[y]+val[i]);
     45                 while(ql<=qr&&Hdis[y]-Hdis[que[ql]]>Hdis[x]-(Hdis[y]-Hdis[que[ql]])) ql++;
     46                 if(ql<=qr) ans=max(ans,Hdis[y]-Hdis[que[ql]]+f[que[ql]]+f[y]);
     47                 while(ql<=qr&&f[y]-Hdis[y]>=f[que[qr]]-Hdis[que[qr]]) qr--;
     48                 que[++qr]=y;
     49             }
     50             for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     51                 int y=to[i];
     52                 while(ql<=qr&&Hdis[x]-(Hdis[que[ql]]-Hdis[y])>Hdis[que[ql]]-Hdis[y]) ql++;
     53                 if(ql<=qr) ans=max(ans,Hdis[x]-(Hdis[que[ql]]-Hdis[y])+f[que[ql]]+f[y]);
     54             }
     55         } if(isnode[x]) ans=max(ans,f[x]);
     56     }
     57 }V;
     58 
     59 int tot,dfn[N],a[N];
     60 bool cmp(const int &A,const int &B) { return dfn[A]<dfn[B]; }
     61 struct Tree {
     62     int ecnt,fir[N],nxt[N],to[N]; LL val[N];
     63     void add(int u,int v,LL w) {
     64         nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
     65         nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
     66         //printf("%d %d %lld
    ",u,v,w);
     67     }
     68     
     69     int R[N],f[N][20]; LL H[N];
     70     void lca(int &cc,int x,int y) {
     71         if(R[x]<R[y]) swap(x,y);
     72         Rep(i,18,0) if(R[f[x][i]]>=R[y])
     73             x=f[x][i];
     74         if(x==y) { a[++cc]=x; return ; }
     75         Rep(i,18,0) if(f[x][i]!=f[y][i])
     76             x=f[x][i],y=f[y][i];
     77         if(f[x][0]>n) {
     78             a[++cc]=x; a[++cc]=y;
     79         }
     80         a[++cc]=f[x][0]; return ;
     81     }
     82     
     83     int dfk,sz[N];
     84     int dfs(int x,int fa) {
     85         sz[x]=1;
     86         f[x][0]=fa;
     87         R[x]=R[fa]+1;
     88         dfn[x]=++dfk;
     89         For(i,1,18) f[x][i]=f[f[x][i-1]][i-1];
     90         for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa) {
     91             H[to[i]]=H[x]+val[i];
     92             dfs(to[i],x);
     93             sz[x]+=sz[to[i]];
     94         }
     95     }
     96     
     97     bool in(int a,int b) { return dfn[a]>=dfn[b]&&dfn[a]<dfn[b]+sz[b]; }
     98     int sta[N],top;
     99     void solve() {
    100         int cnt,sz,rt=0;
    101         read(cnt); sz=cnt;
    102         For(i,1,cnt) { read(a[i]); isnode[a[i]]=1; }
    103         sort(a+1,a+cnt+1,cmp);
    104         For(i,1,cnt-1) {
    105             lca(sz,a[i],a[i+1]);
    106         }
    107         sort(a+1,a+sz+1,cmp);
    108         cnt=unique(a+1,a+sz+1)-(a+1);
    109         For(i,1,cnt) {
    110             if(!rt||R[a[i]]<R[rt]) rt=a[i];
    111             while(top&&!in(a[i],sta[top])) top--;
    112             if(top) V.add(sta[top],a[i],H[a[i]]-H[sta[top]]);
    113             sta[++top]=a[i];
    114         } while(top) top--;
    115         ans=0; V.dfs(rt,0);
    116         printf("%lld
    ",ans);
    117         For(i,1,cnt) { isnode[a[i]]=0; V.fir[a[i]]=0; } V.ecnt=0;
    118     }
    119 }T;
    120 
    121 struct Cactus {
    122     int ecnt,fir[N],nxt[N],to[N],val[N],vis[N];
    123     void add(int u,int v,int w) {
    124         nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
    125         nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
    126     }
    127     
    128     int dfk,dfn[N],low[N],sta[N],top;
    129     void tarjan(int x) {
    130         dfn[x]=low[x]=++dfk;
    131         for(int i=fir[x];i;i=nxt[i]) if(!vis[i]) {
    132             sta[++top]=i;
    133             vis[i]=vis[i^1]=1;
    134             if(!dfn[to[i]]) {
    135                 tarjan(to[i]);
    136                 low[x]=min(low[x],low[to[i]]);
    137                 if(low[to[i]]>=dfn[x]) {
    138                     LL hc=0,nc=0,cc=0;
    139                     T.add(x,++tot,0);
    140                     Rep(j,top,1) {
    141                          hc+=val[sta[j]]; cc++;
    142                         if(sta[j]==i) break;
    143                     }
    144                     Hdis[tot]=hc;
    145                     while(top) {
    146                         int j=sta[top--];
    147                         if(to[j]!=x) {
    148                             if(cc==1) T.add(tot,to[j],hc);
    149                             else T.add(tot,to[j],min(hc-nc,nc));
    150                             Hdis[to[j]]=nc;
    151                         }
    152                         nc+=val[j];
    153                         if(j==i) break;
    154                     }
    155                 }
    156             }
    157             else low[x]=min(low[x],dfn[to[i]]);
    158         }
    159     }
    160     
    161     void init() { ecnt=1; tot=n; }
    162 }C;
    163 
    164 struct hash {
    165     int ecnt;
    166     struct edge{ int u,v,w; }e[N];
    167     vector<int>vc[N];
    168     void ins(int u,int v,int w) {
    169         if(u>v) swap(u,v);
    170         int hs=(u*2333+v)%mod,up=vc[hs].size();
    171         For(i,0,up-1) {
    172             int ec=vc[hs][i];
    173             if(e[ec].u==u&&e[ec].v==v) { e[ec].w=min(e[ec].w,w); return; } 
    174         }
    175         e[++ecnt]=(edge){u,v,w}; vc[hs].push_back(ecnt);
    176     }
    177     
    178     void add() {
    179         For(i,1,ecnt) C.add(e[i].u,e[i].v,e[i].w);
    180     }
    181 }H;
    182 
    183 int main() {
    184     //freopen("1.in","r",stdin);
    185     //freopen("1.out","w",stdout);
    186     read(n); read(m);
    187     For(i,1,m) {
    188         int u,v,w;
    189         read(u); read(v); read(w);
    190         C.add(u,v,w);
    191         H.ins(u,v,w); 
    192     }
    193     C.init(); H.add();
    194     C.tarjan(1); 
    195     T.dfs(1,0);
    196     read(Q);
    197     For(i,1,Q) T.solve();
    198     Formylove;
    199 }
    View Code

    写完花了1.5h找bug发现是数组开小了。

    其实是因为太长实在不想看一直各种磨蹭各种骚扰其他同学。

    无脑圆方树+虚树+单调队列优化dp。

    如果两个人的lca是方点要把方点的两个圆儿子加进去。

    http://uoj.ac/problem/87

  • 相关阅读:
    Java集合(4):Iterator(迭代器)
    Java集合(3):Vector && Stack
    Java集合(2):LinkedList
    面试题29:顺时针打印矩阵
    面试题28:对称的二叉树
    面试题27:二叉树的镜像
    面试题26:树的子结构
    面试题24:反转链表
    面试题25:合并两个排序的链表
    面试题23:链表中环的入口结点
  • 原文地址:https://www.cnblogs.com/Achenchen/p/10472764.html
Copyright © 2020-2023  润新知