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;
}

 

弃坑

posted @ 2017-02-27 08:29  DaD3zZ  阅读(56)  评论(0编辑  收藏  举报