• [BZOJ] 4326: NOIP2015 运输计划


    二分答案,把原问题转化为(log)个判定问题

    现在问题是,给出一个答案(t),问是否可行

    我们找出(len>t)的所有路径,这些路径都要被变短,也就要找到这些路径的一条最长公共边

    如何找最长公共边?先考虑公共边,可以用树上差分解决,最长就顺便取max即可

    //Stay foolish,stay hungry,stay young,stay simple
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cctype>
    using namespace std;
    
    inline int rd(){
    	int ret=0;char c;
    	while(c=getchar(),!isdigit(c));
    	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    	return ret;
    }
    
    const int MAXN =300005,M=300005;
    int n,m;
    struct Edge{
    	int nex,to,w;
    }e[M<<1];
    int ecnt,head[MAXN];
    inline void add(const int x,const int y,const int w){
    	e[++ecnt].nex = head[x];
    	e[ecnt].to = y;
    	e[ecnt].w = w;
    	head[x] = ecnt;
    }
    int fa[MAXN],hs[MAXN],dep[MAXN];
    int dfs1(int x,int pre,int w){
    	fa[x]=pre;dep[x]=dep[pre]+w;
    	int mx=0,tmp,siz=1;
    	for(register int i=head[x];i;i=e[i].nex){
    		int v=e[i].to;
    		if(v==pre) continue;
    		tmp=dfs1(v,x,e[i].w);siz+=tmp;
    		if(tmp>mx){mx=tmp;hs[x]=v;}
    	}
    	return siz;
    }
    int top[MAXN];
    void dfs2(int x,int tp){
    	top[x]=tp;
    	if(hs[x]) dfs2(hs[x],tp);
    	for(register int i=head[x];i;i=e[i].nex){
    		int v=e[i].to;
    		if(v==fa[x]||v==hs[x]) continue;
    		dfs2(v,v);	
    	}
    }
    int lca(int x,int y){
    	while(top[x]!=top[y])
    		dep[top[x]]<dep[top[y]]?y=fa[top[y]]:x=fa[top[x]];
    	return dep[x]<dep[y]?x:y;
    }
    
    struct Links{
    	int x,y,l,len;
    }lk[MAXN];
    int num,mx,val[MAXN];
    int d[MAXN];
    
    void gfs(int x){
    	for(register int i=head[x];i;i=e[i].nex){
    		int v=e[i].to;
    		if(v==fa[x]) continue;
    		gfs(v);
    		d[x]+=d[v];
    	}
    	if(d[x]==num){
    		mx=max(mx,dep[x]-dep[fa[x]]);	
    	}
    }
    bool check(int t){
    	num=0;mx=0;
    	memset(d,0,sizeof(d));
    	int mxl=0;
    	for(register int i=1;i<=m;i++){
    		if(lk[i].len>t){
    			num++;	
    			d[lk[i].x]++;
    			d[lk[i].y]++;
    			d[lk[i].l]-=2;
    			mxl=max(mxl,lk[i].len);
    		}
    		
    	}
    	gfs(1);
    	return (mxl-mx<=t);
    }
    
    signed main(){
    	n=rd();m=rd();
    	int x,y,w;
    	for(register int i=1;i<=n-1;i++){
    		x=rd();y=rd();w=rd();
    		add(x,y,w);add(y,x,w);
    	}
    	dfs1(1,0,0);dfs2(1,1);
    	for(register int i=1;i<=m;i++){
    		x=lk[i].x=rd();
    		y=lk[i].y=rd();
    		int l=lca(x,y);
    		lk[i].l=l;
    		lk[i].len=dep[x]+dep[y]-(dep[l]<<1);
    	}
    	int l=0,r=3e8,mid,ans;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(check(mid))ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	cout<<ans;
    	return 0;
    }
    
    未经许可,禁止搬运。
  • 相关阅读:
    Python find() 方法
    enumerate函数
    【Unity】项目工程源码
    【Unity】UGUI聊天消息气泡 随文本内容自适应
    Unity读Excel 输出PC端(Windows)后不能读取的问题
    【C#】读取Excel中嵌套的Json对象,Json带斜杠的问题(其三)
    【C#】读取Excel中嵌套的Json对象,Json带斜杠的问题(其二)
    【C#】读取Excel中嵌套的Json对象,Json带斜杠的问题(其一)
    Unity输出PC端(Windows) 拖拽文件到app中
    Android Studio报错Error:Failed to open zip file. Gradle's dependency cache may be corrupt
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9781607.html
Copyright © 2020-2023  润新知