BZOJ3459卡不过
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> #include<queue> using namespace std; inline int read() { int x=0; char ch=getchar(); while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x; } #define Rint register int #define INF 0x7fffffff #define MAXN 100010 int N,val[MAXN],son[MAXN],tot; namespace Graph{ struct EdgeNode{ int next,to,cap; }edge[1500010]; int head[MAXN],cnt=1; inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].cap=w;} inline void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,0);} int h[MAXN],cur[MAXN],S,T; inline bool bfs() { queue<int>q; for (int i=S; i<=T; i++) h[i]=-1; h[S]=1; q.push(S); while (!q.empty()) { int now=q.front(); q.pop(); for (Rint i=head[now]; i; i=edge[i].next) if (h[edge[i].to]==-1 && edge[i].cap) h[edge[i].to]=h[now]+1,q.push(edge[i].to); } return h[T]!=-1; } inline int dfs(int loc,int low) { if (loc==T) return low; int used=0,w; for (Rint i=head[loc]; i; i=edge[i].next) if (edge[i].cap && h[edge[i].to]==h[loc]+1) { w=dfs(edge[i].to,min(edge[i].cap,low-used)); edge[i].cap-=w; edge[i^1].cap+=w; used+=w; if (used==low) return low; if (edge[i].to) cur[loc]=i; } h[loc]=-1; return used; } inline int Dinic() { int tmp=0; while (bfs()) tmp+=dfs(S,INF); return tmp; } inline void Clear() {cnt=1; for (int i=S; i<=T; i++) head[i]=0;} } namespace Tree{ struct EdgeNode{ int next,to,dis; }edge[MAXN<<1]; int head[MAXN],cnt=1,fa[MAXN]; inline void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].dis=w;} inline void InsertEdge(int u,int v,int w) {fa[v]=u; AddEdge(u,v,w); AddEdge(v,u,w);} int st[MAXN],dfs,pl[MAXN],pr[MAXN],dist[MAXN]; inline bool cmp(int a,int b) {return dist[a]<dist[b];} inline void DFS_2(int x) { if (!son[x]) st[++dfs]=x; for (Rint i=head[x]; i; i=edge[i].next) if (edge[i].to!=fa[x]) DFS_2(edge[i].to); } inline void DFS(int x) { for (Rint i=head[x]; i; i=edge[i].next) if (edge[i].to!=fa[x]) dist[edge[i].to]=dist[x]+edge[i].dis,DFS(edge[i].to); pl[x]=dfs+1; for (Rint i=head[x]; i; i=edge[i].next) if (edge[i].to!=fa[x]) DFS_2(edge[i].to); pr[x]=dfs; stable_sort(st+pl[x],st+pr[x]+1,cmp); } inline void Prework() {dfs=N; for (Rint i=1; i<=N; i++) if (!fa[i]) DFS(i);} inline void BuildGraph(int tim) { Graph::S=0; Graph::T=dfs+1; Graph::Clear(); int l,r,mid,pos; for (Rint i=1,j; i<=N; i++) if (son[i]) { Graph::InsertEdge(Graph::S,i,val[i]); for (j=i; j; j=fa[j]) if (dist[st[pl[j]]]-dist[j]<=tim+dist[j]-dist[i]) { l=pl[j],r=pr[j],mid,pos=pl[j]; while (l<=r) { mid=(l+r)>>1; if (dist[st[mid]]-dist[j]<=tim+dist[j]-dist[i]) l=mid+1,pos=mid; else r=mid-1; } Graph::InsertEdge(i,pos,INF); } for (j=pl[i]; j<=pr[i]-1; j++) Graph::InsertEdge(j+1,j,INF); } else Graph::InsertEdge(i,Graph::T,val[i]); for (Rint i=N+1; i<=dfs; i++) Graph::InsertEdge(i,st[i],INF); } } int main() { // freopen("bomb.in","r",stdin); // freopen("bomb.out","w",stdout); N=read(); for (Rint i=1; i<=N; i++) { son[i]=read(); for (Rint j=1,x,y; j<=son[i]; j++) x=read(),y=read(),Tree::InsertEdge(i,x,y); val[i]=read(); if (son[i]) tot+=val[i]; } Tree::Prework(); int l=1,r=500000,mid,ans=0; while (l<=r) { mid=(l+r)>>1; Tree::BuildGraph(mid); if (Graph::Dinic()==tot) r=mid-1,ans=mid; else l=mid+1; } printf("%d\n",ans); return 0; }
弃坑
——It's a lonely path. Don't make it any lonelier than it has to be.