首页 > 其他分享 >运输计划

运输计划

时间:2024-05-21 11:08:40浏览次数:13  
标签:运输 int res sum mid 计划 星球 define

[NOIP2015 提高组] 运输计划

题目背景

NOIP2015 Day2T3

题目描述

公元 \(2044\) 年,人类进入了宇宙纪元。

L 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 L 国的所有星球。

小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 \(u_i\) 号星球沿最快的宇航路径飞行到 \(v_i\) 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 \(j\),任意飞船驶过它所花费的时间为 \(t_j\),并且任意两艘飞船之间不会产生任何干扰。

为了鼓励科技创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小 P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。

在虫洞的建设完成前小 P 的物流公司就预接了 \(m\) 个运输计划。在虫洞建设完成后,这 \(m\) 个运输计划会同时开始,所有飞船一起出发。当这 \(m\) 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。

如果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?

输入格式

第一行包括两个正整数 \(n, m\),表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 \(1\) 到 \(n\) 编号。

接下来 \(n-1\) 行描述航道的建设情况,其中第 \(i\) 行包含三个整数 \(a_i, b_i\) 和 \(t_i\),表示第 \(i\) 条双向航道修建在 \(a_i\) 与 \(b_i\) 两个星球之间,任意飞船驶过它所花费的时间为 \(t_i\)。

数据保证

接下来 \(m\) 行描述运输计划的情况,其中第 \(j\) 行包含两个正整数 \(u_j\) 和 \(v_j\),表示第 \(j\) 个运输计划是从 \(u_j\) 号星球飞往 \(v_j\)号星球。

输出格式

一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

样例 #1

样例输入 #1

6 3 
1 2 3 
1 6 4 
3 1 7 
4 3 6 
3 5 5 
3 6 
2 5 
4 5

样例输出 #1

11

提示

所有测试数据的范围和特点如下表所示

请注意常数因子带来的程序效率上的影响。

对于 \(100\%\) 的数据,保证:\(1 \leq a_i,b_i \leq n\),\(0 \leq t_i \leq 1000\),\(1 \leq u_i,v_i \leq n\)。

这题可以用LCA或树链剖分
方法很多

23_9G写法

每次描述运输计划的情况时,算出x->y的总时间,然后记录路径,把路径外的max只更新一下(如图下)
image
然后统计出那一条路径权值最大,一定是改这条路径上的一条边
最后依次遍历(从下往上一个一个点走)比较res=min(res,max(sum-a[x],quemx(1,dfn[x])))这个意思是比较当前这个点所在的路径上次大边所用的最大时间和最大边减去相应边权,最终要取最小的答案

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+5;
int n,m,xx,yy,sum,a[N];
int head[N],tot;
struct E{int u,v,w;} e[N<<1];
inline void add(int u,int v,int w){e[++tot]={head[u],v,w}; head[u]=tot;}

int son[N],dep[N],fa[N],sz[N],top[N],dfn[N],cnt,rk[N];
void dfs1(int u,int f)
{
	sz[u]=1; son[u]=-1; fa[u]=f; dep[u]=dep[f]+1;
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v==f) continue;
		a[v]=e[i].w;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(son[u]==-1||sz[son[u]]<sz[v]) son[u]=v;
	}
}
void dfs2(int u,int t)
{
	top[u]=t; dfn[u]=++cnt; rk[cnt]=u;
	if(son[u]==-1) return;
	dfs2(son[u],t);
	for(int i=head[u];i;i=e[i].u)
	{
		int v=e[i].v;
		if(v^fa[u]&&v^son[u]) dfs2(v,v);
	}
}
struct T
{
	int l,r,sum,mx,lz;
	#define l(x) tr[x].l
	#define r(x) tr[x].r
	#define sum(x) tr[x].sum
	#define mx(x) tr[x].mx
	#define lz(x) tr[x].lz
	#define ls(x) (x << 1)
	#define rs(x) (x << 1 | 1)
} tr[N<<2];
void down(int k)
{
	if(lz(k))
	{
		mx(ls(k))=max(mx(ls(k)),lz(k));
		mx(rs(k))=max(mx(rs(k)),lz(k));
		lz(ls(k))=max(lz(ls(k)),lz(k));
		lz(rs(k))=max(lz(rs(k)),lz(k));	
		lz(k)=0;	
	}
}
void update(int k,int l,int r,int v)
{
	if(l(k)>=l&&r(k)<=r) {mx(k)=max(mx(k),v); lz(k)=max(lz(k),v); return;}
	down(k);
	int mid=l(k)+r(k)>>1;
	if(l<=mid) update(ls(k),l,r,v);
	if(r>mid) update(rs(k),l,r,v);
	mx(k)=max(mx(ls(k)),mx(rs(k)));
}
int quemx(int k,int p)
{
	if(l(k)==r(k)) return mx(k);
	down(k);
	int mid=l(k)+r(k)>>1;
	if(p<=mid) return quemx(ls(k),p);
	else return quemx(rs(k),p);
}

void bui(int k,int l,int r)
{
	l(k)=l; r(k)=r;
	if(l==r) {sum(k)=a[rk[l]]; return;}
	int mid=l+r>>1;
	bui(ls(k),l,mid); bui(rs(k),mid+1,r);
	sum(k)=sum(ls(k))+sum(rs(k));
}
int quesum(int k,int l,int r)
{
	if(l<=l(k)&&r>=r(k)) return sum(k);
	int mid=l(k)+r(k)>>1,res=0;
	if(l<=mid) res+=quesum(ls(k),l,r);
	if(r>mid) res+=quesum(rs(k),l,r);
	return res;
}

int quepath(int x,int y)
{
	int res=0;
	while(top[x]^top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		res+=quesum(1,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	res+=quesum(1,dfn[x]+1,dfn[y]);
	return res;
}

#define fi first
#define se second
pair<int,int> q[N];
void mdfmx(int x,int y,int now)
{
	q[0].fi=0;
	while(top[x]^top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		q[++q[0].fi]=make_pair(dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	q[++q[0].fi]=make_pair(dfn[x]+1,dfn[y]);
	sort(q+1,q+1+q[0].fi);
	if(q[1].fi>1) update(1,1,q[1].fi-1,now);
	if(q[q[0].fi].se<n) update(1,q[q[0].fi].se+1,n,now);
	for(int i=1;i<q[0].fi;i++) update(1,q[i].se+1,q[i+1].fi-1,now);


}
int find(int x,int y)
{
	int res=2147483647;
	if(x==y) return 0;
	if(dep[x]<dep[y]) swap(x,y);
	while(dep[x]!=dep[y]) res=min(res,max(sum-a[x],quemx(1,dfn[x]))),x=fa[x];
	while(x!=y)
	{
		if(dep[x]<dep[y]) swap(x,y);
		res=min(res,max(sum-a[x],quemx(1,dfn[x])));x=fa[x];
	}
	return res;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++)
	{
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		add(x,y,z); add(y,x,z);
	}
	dfs1(1,0); dfs2(1,1); bui(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int x,y; scanf("%d%d",&x,&y);
		int tmp=quepath(x,y);
		mdfmx(x,y,tmp);
		if(tmp>=sum) xx=x,yy=y,sum=tmp;
	}
	printf("%d\n",find(xx,yy));
	return 0;
}

23_wlesq做法

点击查看代码
#include <bits/stdc++.h>
//#define ll long long
#define int long long
#define rint int
#define mk make_pair
#define pb push_back
#define lid (rt<<1)
#define rid (rt<<1|1)
using namespace std;
const int N =3e5+5;
int n,cnt,head[N*2],w[N],rnk[N],dfn[N],dep[N],fa[N],son[N],top[N],size[N],ntime,m;
int read()
{
	int x=0,f=1;char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-f;
	for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
struct qur
{
	int l,r,lca,v;
}qu[N];
struct Edge
{
	int u,to,w,next;
}edge[N*2];
void add(int u,int v,int w)
{
	edge[++cnt].u=u;
	edge[cnt].to=v;
	edge[cnt].next=head[u];
	edge[cnt].w=w;
	head[u]=cnt;
}
struct Tree
{
	int l,r;
	int cnt,lz;
}st[N*16];
void pushup(int rt)
{
	st[rt].cnt=st[lid].cnt+st[rid].cnt;
}
void pushdown(int rt)
{
	if(st[rt].lz)
	{
		int lz=st[rt].lz;st[rt].lz=0;
		st[lid].lz+=lz;st[rid].lz+=lz;
		st[lid].cnt+=1ll*lz*(st[lid].r-st[lid].l+1);
		st[rid].cnt+=1ll*lz*(st[rid].r-st[rid].l+1);
	}
}
void bt(int rt,int l,int r)
{
	st[rt].l=l;st[rt].r=r;
	if(l==r)
	{
		st[rt].cnt=w[rnk[l]];
		return;
	}
	int mid=(l+r)>>1;
	bt(lid,l,mid);bt(rid,mid+1,r);
	pushup(rt);
}
void update(int rt,int l,int r,int val)
{
	if(l<=st[rt].l&&st[rt].r<=r)
	{
		st[rt].cnt=val;
//		cout<<rt<<" "<<val<<endl;;
//		st[rt].lz+=val;
		return;
	}
//	pushdown(rt);
	int mid=(st[rt].l+st[rt].r)>>1;
	if(l<=mid)update(lid,l,r,val);
	if(r>mid)update(rid,l,r,val);
	pushup(rt);
}
int query(int rt,int l,int r)
{
	if(l<=st[rt].l&&st[rt].r<=r)
	{
		return st[rt].cnt;
	}
	int mid=(st[rt].l+st[rt].r)>>1;
	int ans=0;
	if(l<=mid)ans+=query(lid,l,r);
	if(r>mid)ans+=query(rid,l,r);
	return ans;
}
void ffind(int u,int _fa,int depth)
{
	int ms=0;
	fa[u]=_fa;
	son[u]=0;
	dep[u]=depth;
	size[u]=1;
	for(int i=head[u];i;i=edge[i].next)
	{
		int to=edge[i].to;
		if(dep[to])continue;
//		cout<<to<<endl;
		w[to]=edge[i].w;
		ffind(to,u,depth+1);
		size[u]+=size[to];
		if(ms<size[to])
		{
			son[u]=to;
			ms=size[to];
		}
	}
}
void connect(int u,int asct)
{
	dfn[u]=++ntime;
	top[u]=asct;
	rnk[ntime]=u;
	if(son[u])
	{
		connect(son[u],asct);
	}
	for(int i=head[u];i;i=edge[i].next)
	{
		int to=edge[i].to;
		if(to==son[u]||to==fa[u])continue;
		connect(to,to);
	}
}
int Q(int l,int r,int id)
{
	int ans=0;
//	cout<<l<<" "<<r<<" ";
	while(top[l]!=top[r])
	{
		if(dep[top[l]]<dep[top[r]])swap(l,r);
		ans+=query(1,dfn[top[l]],dfn[l]);
		l=fa[top[l]];
	}
	if(dep[l]>dep[r])swap(l,r);
	ans+=query(1,dfn[son[l]],dfn[r]);
	if(id)qu[id].lca=l;
	if(id)qu[id].v=ans;
//	cout<<l<<endl;
	return ans;
}
int f[N];
void dfs(int u,int fa)
{
	for(int i=head[u];i;i=edge[i].next)
	{
		int to=edge[i].to;
		if(to!=fa)
		{
			dfs(to,u);
			f[u]+=f[to];
		}
	}
}
bool check(int mid)
{
	int cnt=0;int maxlen=0;
	for(int i=1;i<=n;i++)f[i]=0;
	int i;
	for(i=m;i>=1;i--)
	{
		if(qu[i].v>mid)
		{
			f[qu[i].l]++;f[qu[i].r]++;
			f[qu[i].lca]-=2;
			cnt++;
		}
	}
	if(i==m)return true;
	dfs(1,0);
//	cout<<mid<<endl;
	for(int i=1;i<=n;i++)
	{
		if(f[i]==cnt)
		{
			maxlen=max(w[i],maxlen);
		}
	}
	return qu[m].v-maxlen<=mid;
}
bool cmp(qur a,qur b)
{
	return a.v<b.v;
}
signed main()
{
	//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//	freopen("P2680_10.in","r",stdin);
//	cin>>n>>m;
	n=read();m=read();
	int a,b,t;
	for(int i=1;i<n;i++)
	{
//		cin>>a>>b>>t;
		a=read();b=read();t=read();
		add(a,b,t);add(b,a,t);
	}
	int sum=0;
	ffind(1,0,1);
	connect(1,1);
	bt(1,1,n);
	int tot=LONG_LONG_MAX;
	for(int i=1;i<=m;i++)
	{
		a=read();b=read();
		qu[i]={a,b};
		Q(a,b,i);	
	}	
	sort(qu+1,qu+1+m,cmp);
	int l=0,ans=0,r=qu[m].v;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(check(mid))
		{
			r=mid-1;
			ans=mid;
		}else
		{
			l=mid+1;
		}
	}
	cout<<ans;
	return 0;
}
这是相对较慢的做法,需用到树链剖分,树上差分
先统计出x->y

标签:运输,int,res,sum,mid,计划,星球,define
From: https://www.cnblogs.com/wlesq/p/18203404

相关文章

  • 测试计划与测试内容的区别
    测试方案、测试计划、测试策略与测试用例之间的区别?测试方案:测试工具的设计和选择,测试用例的设计方法,测试代码的设计方案。测试方案需要在测试计划的指导下进行,测试计划提出“做什么”,而测试方案明确“如何做“。一个行动方案,一个偏执行。测试计划:1、对测试全过程的组织、资......
  • 存钱计划(三)
    存钱计划(三)时间限制(普通/Java):1000MS/30000MS内存限制:65536KByte描述TZC的店铺比较多,上次WY随便走只要能走到就行,现在他学聪明了。WY去买东西的话,确定一家店以后,当然他先要想想怎么样走到那家店走的路最少。店与店之间是有走的方向的,从店A到店B可以,店B到店A未必可以。店与......
  • 使用django_celery_beat在admin后台配置计划任务
    使用步骤安装包pipinstalldjango-celery-beatapp注册app注册INSTALLED_APPS=[....'django_celery_beat',]配置文件:屏蔽原来的调度器CELERY_BEAT_SCHEDULER='django_celery_beat.schedulers.DatabaseScheduler'设置时区LANGUAGE_CODE='z......
  • 第12周]比较不同团队的绩效评估方法;提出自己团队的绩效评估计划
    针对我的团队制定的绩效评估计划包括:1.目标设定阶段:与每位团队成员一对一会谈,讨论和确认接下来一个时间段的SMART目标或OKRs。确保目标与公司的整体战略一致。2.中期检查:在目标期限的中间阶段,举行简短会议,检查每位成员的进度。这是调整目标、解决问题和提供支持的机会。中期检......
  • 比较不同团队的绩效评估方法;提出自己团队的绩效评估计划在学习通提交解答的同时,可以
    ]比较不同团队的绩效评估方法;提出自己团队的绩效评估计划在学习通提交解答的同时,可以同步发布在团队和个人博客上,作为学习心得体会,记录下来【第二组】答:不同团队的绩效评估方法会因公司文化、业务需求和团队特点而有所不同。以下是一些常见的团队绩效评估方法,以及可能适用于你......
  • 超简洁的todolist工具,电脑桌面高效计划管理软件
    对于上班族来说,在电脑上使用一款高效计划管理软件至关重要。这样的工具不仅能帮助我们清晰地规划和追踪工作任务,还能有效提高工作效率,减少遗漏和延误。例如,当我们面临多个项目并行时,通过管理软件可以一目了然地查看各项任务的进度和优先级,从而合理分配时间和精力。那么,哪款电脑桌......
  • 加固计划书
    加固计划书SDL介绍安全开发生命周期(SDL)是一种软件开发方法论,旨在通过将安全性纳入软件开发的各个阶段来创建更安全、更健壮的软件。SDL由一系列阶段和活动组成,涵盖了从需求分析到维护的整个软件开发生命周期。以下是SDL的主要阶段和相关活动:需求分析阶段:安全需求收集:确定......
  • 计划做点事情-跳槽
    【最近想做什么了】最近想跳槽了【为什么要做这个】现在的待遇有点低,或者说是太低了,想起来就觉得惨,难受,羞愧;目前看,在当前公司没有发展前景,升级调薪机会不大,也太慢了;转岗OD要再等一年多,而且,政策千变万化,到时候大概率就不满足要求了,也可能拿不到什么好待遇;通勤辛苦,地铁久,开车......
  • SQLServer统计监控SQL执行计划突变的方法
    使用动态管理视图(DMVs)来检测SQL执行计划的突变,你需要关注那些能够提供查询执行统计和计划信息的视图。以下是一些可以用于此目的的DMVs以及相应的查询示例:sys.dm_exec_query_stats:这个视图提供了关于SQLServer中查询执行的统计信息,包括CPU时间、总工作时间、执行次数等。SEL......
  • 使用windows任务计划程序时提示管理员拒绝
    使用Windows任务计划程序时提示管理员拒绝在Windows操作系统中,任务计划程序是一个非常实用的工具,可以用来定时执行一些特定的任务。然而,在使用过程中,可能会遇到一些问题,例如在使用任务计划程序时提示管理员拒绝。本文将介绍这个问题的原因以及解决方法。一、问题原因在使用Win......