Submission #4575

#TimeUsernameProblemLanguageResultExecution timeMemory
4575cki86201Toll (APIO13_toll)C++98
100 / 100
1408 ms102596 KiB
#include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<math.h> #include<stdlib.h> #include<set> #include<ctype.h> using namespace std; #define X first #define Y second typedef long long ll; typedef pair<int,int> Pi; #define Me(x) memset(x,0,sizeof(x)) // O( 2^K*K^2 + M); const int MV = 100010; const int ME = 600060; int N,M,K; struct UF{ int p[MV],mem[MV]; void init(int x){for(int i=1;i<=x;i++)p[i]=i,mem[i]=1;} int Find(int x){ while(x!=p[x])x=p[x]; return x; } bool Union(int x,int y){ x=Find(x),y=Find(y); if(x==y)return false; if(mem[x]>mem[y])p[y]=x; else p[x]=y; if(mem[x]==mem[y])mem[y]++; return true; } }uf; struct Graph{ int st[MV], en[ME], len[ME], next[ME]; int c; Graph(){c=1;} void init(int x){for(int i=1;i<=x;i++)st[i]=0;c=1;} inline void addedge(int s,int d,int l){++c,next[c]=st[s],st[s]=c,en[c]=d,len[c]=l;} void add(int s,int d,int l){addedge(s,d,l),addedge(d,s,l);} }I,MST; struct LittleGraph{ int st[22], en[45], len[45], next[45]; int c; LittleGraph(){c=1;} void init(){Me(st),c=1;} inline void addedge(int s,int d,int l){++c,next[c]=st[s],st[s]=c,en[c]=d,len[c]=l;} void add(int s,int d,int l){addedge(s,d,l),addedge(d,s,l);} int getmax(int s,int d){ int Q[22],i,fr=1,re=0,pre[22],ret=-1; bool chk[22]; Me(chk); Q[0]=s,chk[s]=1; while(fr>re){ for(i=st[Q[re++]];i;i=next[i]){ int t=en[i]; if(chk[t])continue; Q[fr++]=t; chk[t]=1; pre[t]=i; if(t==d){ int tmp=d; while(tmp!=s){ int u=pre[tmp]; if(ret<len[u])ret=len[u]; tmp=en[u^1]; } return ret; } } } } }T[1<<17],GR; int inp[MV]; int gro[MV]; ll wi[23]; int Ka; int sor[1000010]; ll ans; Pi add[23]; bool cut[MV<<1]; bool check[MV]; ll wei[23]; bool chk[23]; void make_mst() { uf.init(N); int i; for(i=1;i<=1000000;i++){ if(sor[i]){ int x=I.en[sor[i]<<1],y=I.en[sor[i]<<1|1]; if(uf.Union(x,y)){ MST.add(x,y,I.len[sor[i]<<1]); } } } } void dfs(int x,int c) { gro[x]=c; wi[c]+=inp[x]; check[x]=1; for(int i=MST.st[x];i;i=MST.next[i]){ if(!check[MST.en[i]]&&!cut[i])dfs(MST.en[i],c); } } void make_mst2() { uf.init(N); int i; for(i=0;i<K;i++)uf.Union(add[i].X,add[i].Y); for(i=1;i<N;i++){ if(!uf.Union(MST.en[i<<1],MST.en[i<<1|1]))cut[i<<1]=cut[i<<1|1]=1; } for(i=1;i<=N;i++)if(!check[i])dfs(i,++Ka); for(i=1;i<N;i++){if(cut[i<<1])GR.add(gro[MST.en[i<<1]],gro[MST.en[i<<1|1]],MST.len[i<<1]);} for(i=0;i<K;i++)add[i].X=gro[add[i].X],add[i].Y=gro[add[i].Y]; } int getInt() { ABC: int a=0; char c=getchar(); while(isdigit(c)){ a=(a<<3)+(a<<1)+c-'0'; c=getchar(); } if(a==0)goto ABC; return a; } ll getans(int a,int x) { chk[x]=1; ll ret=0; for(int i=T[a].st[x];i;i=T[a].next[i]){ if(chk[T[a].en[i]])continue; int d=T[a].en[i]; ret+=getans(a,d); wei[x]+=wei[d]; if(T[a].len[i]<0)ret+=wei[d]*(-T[a].len[i]); } wei[x]+=wi[x]; return ret; } void bfs(int a,int s,int d,int l,int ver) { int Q[22],pre[22],fr=1,re=0,i; Me(chk); Q[0]=s; chk[s]=1; while(fr>re){ for(i=T[a].st[Q[re++]];i;i=T[a].next[i]){ int t=T[a].en[i]; if(chk[t])continue; Q[fr++]=t; chk[t]=1; pre[t]=i; if(t==d){ int tmp=t; while(tmp!=s){ int u=pre[tmp]; if(ver && T[a].len[u] == -1e8)T[a].len[u]=T[a].len[u^1]=-l; if(!ver && T[a].len[u]<0){ T[a].len[u]=T[a].len[u^1]=max(-l,T[a].len[u]); } tmp=T[a].en[u^1]; } return; } } } } ll solve(int x) { int a=0; while((x&(1<<a))==0)a++; int t=x-(1<<a); int m=T[t].getmax(add[a].X,add[a].Y); if(m<=0)return -1; int s,d; for(int i=1;i<Ka;i++){ if(T[t].len[i<<1] == m)s=T[t].en[i<<1],d=T[t].en[i<<1|1]; else T[x].add(T[t].en[i<<1],T[t].en[i<<1|1],T[t].len[i<<1]); } T[x].add(add[a].X,add[a].Y,-m); bfs(x,s,d,m,0); Me(chk),Me(wei); return getans(x,1); } ll put(int x) { uf.init(Ka); int i; for(i=0;i<K-17;i++){ if(x&(1<<i)){ if(uf.Union(add[i+17].X,add[i+17].Y))T[0].add(add[i+17].X,add[i+17].Y,-1e8); } } for(i=1;i<Ka;i++){ int x=GR.en[i<<1],y=GR.en[i<<1|1]; if(uf.Union(x,y))T[0].add(x,y,GR.len[i<<1]); else bfs(0,x,y,GR.len[i<<1],1); } Me(chk),Me(wei); return getans(0,1); } void Init() { for(int i=0;i<(1<<17);i++)T[i].init(); } int main() { N=getInt(),M=getInt(),K=getInt(); int i; for(i=1;i<=M;i++){ int x=getInt(),y=getInt(),z=getInt(); sor[z]=i; I.add(x,y,z); } for(i=0;i<K;i++)add[i].X=getInt(),add[i].Y=getInt(); for(i=1;i<=N;i++)inp[i]=getInt(); make_mst(); make_mst2(); for(i=0;i<(1<<K);i++){ if(i%(1<<17)==0){ Init(); ll a=put(i>>17); ans=max(ans,a); } else{ ll a=solve((i%(1<<17))); ans=max(ans,a); } } printf("%lld",ans); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...