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 }
写完花了1.5h找bug发现是数组开小了。
其实是因为太长实在不想看一直各种磨蹭各种骚扰其他同学。
无脑圆方树+虚树+单调队列优化dp。
如果两个人的lca是方点要把方点的两个圆儿子加进去。
http://uoj.ac/problem/87