暑假集训8.10-网络流套树剖套线段树
题目:dtoj2797旅行商
其实就是裸的网络流套树剖套线段树其实代码不难码
emmmmmm我决定草率的直接上代码,这可能是一条无营养的博客....
#include<bits/stdc++.h> #define _(d) while(d(isdigit(ch=getchar()))) #define il inline using namespace std; const int N=2e5+5,M=4e6+5,inf=2e9;int n,m,ne[M],to[M],head[N],v[M],d[N],val[N],s,t,ans; int ne1[N<<1],to1[N<<1],head1[N],fa[N],sz[N],son[N],d1[N],idx[N],tot,num[N],top[N],cnt;queue<int> q; int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch-48;_()x=x*10+ch-48;return f*x;} il void insert(int x,int y,int z){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;v[cnt]=z;} il void add(int u,int v,int w){insert(u,v,w);insert(v,u,0);} il void ins(int x,int y){ne1[++cnt]=head1[x];head1[x]=cnt;to1[cnt]=y;} il bool bfs(){ memset(d,-1,sizeof(d));q.push(s);d[s]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=head[x];i;i=ne[i]){ if(!v[i]||d[to[i]]!=-1)continue; q.push(to[i]);d[to[i]]=d[x]+1; } } return d[t]!=-1; } int dfs(int x,int f){ if(x==t)return f;int w,used=0; for(int i=head[x];i;i=ne[i]){ if(d[x]+1!=d[to[i]]||(!v[i]))continue; w=f-used;w=dfs(to[i],min(w,v[i])); v[i]-=w;v[i^1]+=w;used+=w;if(used==f)return used; } if(!used)d[x]=-1;return used; } il void dinic(){while(bfs()){ans+=dfs(s,inf);}} void dfs1(int x){ sz[x]=1;int maxn=-1; for(int i=head1[x];i;i=ne1[i]){ if(to1[i]==fa[x])continue; d1[to1[i]]=d1[x]+1;fa[to1[i]]=x;dfs1(to1[i]); sz[x]+=sz[to1[i]];if(sz[to1[i]]>maxn)maxn=sz[to1[i]],son[x]=to1[i]; } } void dfs2(int x,int rt){ top[x]=rt;idx[x]=++tot;num[tot]=x; if(!son[x])return;dfs2(son[x],rt); for(int i=head1[x];i;i=ne1[i]){ if(idx[to1[i]])continue;dfs2(to1[i],to1[i]); } } void build(int x,int l,int r){ if(l==r){add(m+x,t,val[num[l]]);return;} int mid=(l+r)>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r); add(m+x,m+(x<<1),inf);add(m+x,m+(x<<1|1),inf); } void intervallink(int x,int l,int r,int ql,int qr,int k){ if(ql<=l&&r<=qr){add(k,m+x,inf);return;} int mid=(l+r)>>1; if(ql<=mid)intervallink(x<<1,l,mid,ql,qr,k); if(mid<qr)intervallink(x<<1|1,mid+1,r,ql,qr,k); } il void Treelink(int x,int y,int k){ while(top[x]!=top[y]){ if(d1[top[x]]<d1[top[y]])swap(x,y); intervallink(1,1,n,idx[top[x]],idx[x],k);x=fa[top[x]]; } if(d1[x]>d1[y])swap(x,y);intervallink(1,1,n,idx[x],idx[y],k); } int main() { n=read();m=read();t=m+4*n+1;for(int i=1;i<=n;i++)val[i]=read(); for(int i=1;i<n;i++){int u,v;u=read();v=read();ins(u,v);ins(v,u);}cnt=1; d1[1]=1;dfs1(1);dfs2(1,1);build(1,1,n); for(int i=1;i<=m;i++){int a,b,c;a=read();b=read();c=read();add(s,i,c);Treelink(a,b,i);} dinic();printf("%d\n",ans); return 0; }