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\n",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\n",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\n",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

posted @ 2019-03-04 19:54  啊宸  阅读(277)  评论(0编辑  收藏  举报