• 【NOIP2015提高组】运输计划


    更新!

    表示之前的方法只能过95分的数据。最后一个会T飞~
    所以,经过努力的奋斗,我终于过了!!

    解法一:

    这题我们要求最值,可以考虑二分答案。
    二分答案,如何判断能否在mid的时间内完成呢?
    我们可以用差分。将那些物流时间>mid的链(设有tot条,其中最多比mid它maxx)加入差分数组中,
    然后将整个树遍历一遍,我们对于每一条边看看它有没有tot条经过且这条边的时间>=maxx。
    如果有,那么OK,反之。
    然后,我们来看看如何来求LCA。
    简单!倍增啊!可惜倍增不行。。。TLE95分
    然后我们只好打tarjan_LCA或神奇(竟然能过?!)的树链剖分LCA了。
    只要代码打的不是很丑,应该都能A了。
    解法二暂时不提供(作者没打。。。)

    Code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 300010
    using namespace std;
    struct node{int v,fr,t;}e[N<<1],g[N<<1];
    int tail[N],head[N],dep[N],fat[N],ti[N],fa[N];
    int a[N][4],o[N],t[N],cnt=0,cnt1=0;
    int n,m,l=0,r=0,mid,len,gr;
    bool bz[N];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void add(int u,int v,int t) {e[++cnt]=(node){v,tail[u],t}; tail[u]=cnt;}
    
    void add1(int u,int v,int t) {g[++cnt1]=(node){v,head[u],t}; head[u]=cnt1;}
    
    void dfs(int x)
    {
    	o[++o[0]]=x;
    	for (int p=tail[x],v;p;p=e[p].fr)
    	{
    		v=e[p].v;
    		if (fat[v]) continue;
    		dep[v]=dep[x]+1,fat[v]=x;
    		ti[v]=ti[x]+e[p].t,dfs(v);
    	}
    }
    
    int gf(int x) {return !fa[x] ? x:fa[x]=gf(fa[x]);}
    
    void tarjan(int x)
    {
    	for (int p=head[x],v,fr;p;p=g[p].fr)
    	{
    		v=g[p].v;
    		if (!bz[v]) continue;
    		fr=g[p].t;
    		a[fr][3]=gf(v);
    		a[fr][2]=ti[x]+ti[v]-(ti[a[fr][3]]<<1);
    		r=max(r,a[fr][2]); 
    	}
    	for (int p=tail[x],v;p;p=e[p].fr)
    	{
    		v=e[p].v;
    		if (bz[v]) continue;
    		bz[v]=1,tarjan(v),fa[v]=x;
    	}
    }
    
    bool pd(int x)
    {
    	int maxx=0,tot=0;
    	memset(t,0,sizeof(t));
    	for (int i=1;i<=m;i++)
    		if (a[i][2]>x)
    		{
    			t[a[i][0]]++,t[a[i][1]]++,tot++;
    			t[a[i][3]]-=2,maxx=max(maxx,a[i][2]-x);
    		}
    	for (int i=o[0];i>0;i--)
    		t[fat[o[i]]]+=t[o[i]];
    	for (int i=1;i<=n;i++)
    		if (t[i]==tot && ti[i]-ti[fat[i]]>=maxx) return 1;
    	return 0;
    }
    
    int main()
    {
    	freopen("transport.in","r",stdin);
    //	freopen("transport.out","w",stdout);
    	n=read(),m=read();
    	for (int i=1,u,v,t;i<n;i++)
    	{
    		u=read(),v=read(),t=read();
    		add(u,v,t),add(v,u,t);
    	}
    	dfs(1);
    	for (int i=1;i<=m;i++)
    	{
    		a[i][0]=read(),a[i][1]=read();
    		add1(a[i][0],a[i][1],i),add1(a[i][1],a[i][0],i);
    	}
    	tarjan(1); 
    	while (l<=r)
    	{
    		mid=l+r>>1;
    		if (pd(mid)) r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",l);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    Nginx 启动错误 Failed to read PID from /run/nginx.pid
    CentOS7 下 nginx 无法加载 Django 静态文件的问题
    SSD + 机械硬盘装 CentOS 分区的问题
    CentOS7 单机维护模式
    编译安装 redis 6.2.1
    谷歌师兄刷题笔记
    我用 DCL 写出了单例模式,结果阿里面试官不满意!
    红黑树杀人事件始末
    头条二面:详述一条 SQL 的执行流程
    jvisual远程 springBoot项目
  • 原文地址:https://www.cnblogs.com/jz929/p/11817782.html
Copyright © 2020-2023  润新知