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.
浙公网安备 33010602011771号