首页 > 其他分享 >洛谷 P2680 [NOIP2015 提高组] 运输计划

洛谷 P2680 [NOIP2015 提高组] 运输计划

时间:2024-08-30 09:15:34浏览次数:15  
标签:NOIP2015 洛谷 int 边权 P2680 mid fa 最大值 dis

洛谷 P2680 [NOIP2015 提高组] 运输计划

题意

给出一棵树和 \(m\) 条路径,可以选择一条边,把边权改为 \(0\),求 \(m\) 条路经长度最大值的最小值。

思路

看到最大值最小,可以想到二分答案,答案具有单调性。

考虑如何判定答案 \(x\) 是否可行。

统计所有长度大于 \(x\) 的路径,统计它们共同经过的边和长度的最大值。

如果把它们共同经过的一条边权改为 \(0\) 后,长度最大值缩小到 \(x\) 以下,则答案可行。

统计共同经过的边可以使用边权树上差分,统计每条边被经过的次数。

如果某条边被经过的次数等于长度大于 \(x\) 的路径数量,则它就被共同经过。

如果没有长度大于 \(x\) 的边,答案显然可行。

直接暴力二分 \(0\) 到极大值会时间超限。

求出最大边权 \(W\) 和所有路径长度最大值 \(M\),二分区间为 \([W,M-W]\)。

因为最多把最大边权设为 \(0\)。\(W \le 1000\),可以通过。

时间复杂度:\(O((n+m)\log W)\)。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 300005 + 5;
const int mod = 998244353;
int tot, ver[N << 1], nxt[N << 1], head[N], edge[N << 1];
int n, m, fa[N][20], de[N], dis[N], a[N];
struct path {int u, v, lca, w;};
path p[N];
void add(int x, int y, int z) {
	ver[++ tot] = y;
	nxt[tot] = head[x];
	head[x] = tot;
	edge[tot] = z;
}
void DFS(int x) {
    de[x] = de[fa[x][0]] + 1;
    for (int i = 1; i <= 19; i ++)
        fa[x][i] = fa[fa[x][i - 1]][i - 1];
    for (int i = head[x], y; i; i = nxt[i]) {
        y = ver[i];
        if (y == fa[x][0]) continue;
        fa[y][0] = x, dis[y] = dis[x] + edge[i];
        DFS(y);
    }
}
inline int LCA(int x, int y) {
    if (de[x] < de[y]) swap(x, y);
    for (int i = 19; i >= 0; i --) 
        if (de[fa[x][i]] >= de[y]) x = fa[x][i];
    if (x == y) return x;
    for (int i = 19; i >= 0; i --)
        if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}
void dfs(int x) {
	for (int i = head[x], y; i; i = nxt[i]) {
		if ((y = ver[i]) == fa[x][0]) continue;
		dfs(y);
		a[x] += a[y];
	}
}
bool check(int x) {
	memset(a, 0, sizeof(a));
	int cnt = 0, mx = 0;
	for (int i = 1; i <= m; i ++) {
		if (p[i].w > x) {
			a[p[i].u] ++;
			a[p[i].v] ++;
			a[p[i].lca] -= 2;
			cnt ++;
			mx = max(mx, p[i].w); 
		}
	}
	if (!cnt) return 1;
	dfs(1);
	for (int i = 2; i <= n; i ++) 
		if (a[i] >= cnt && mx - dis[i] + dis[fa[i][0]] <= x) return 1;
	return 0;
}
int main() {
	scanf("%d%d", &n, &m);
	int MAXW = 0;
	for (int i = 1, u, v, w; i < n; i ++) {
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w); add(v, u, w);
		MAXW = max(MAXW, w);
	}
	DFS(1);
	int maxw = 0; 
	for (int i = 1, u, v; i <= m; i ++) {
		cin >> u >> v;
		p[i] = {u, v, LCA(u, v), dis[u] + dis[v] - 2 * dis[LCA(u, v)]};
		maxw = max(maxw, p[i].w);
	}
	int l = maxw - MAXW, r = maxw, mid, res;
	while (l <= r) {
		mid = (l + r) >> 1;
		if (check(mid)) r = mid - 1, res = mid;
		else l = mid + 1;
	}
	printf("%d\n", res);
	return 0;
}  

标签:NOIP2015,洛谷,int,边权,P2680,mid,fa,最大值,dis
From: https://www.cnblogs.com/maniubi/p/18387946

相关文章

  • 信息学奥赛初赛天天练-78-NOIP2015普及组-基础题3-中断、计算机病毒、文件传输协议FTP
    NOIP2015普及组基础题38所谓的“中断”是指()A操作系统随意停止一个程序的运行B当出现需要时,CPU暂时停止当前程序的执行转而执行处理新情况的过程C因停机而停止一个程序的运行D电脑死机9计算机病毒是()A通过计算机传播的危害人体健康的一种......
  • 洛谷P5322 [BJOI2019] 排兵布阵 题解
    代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongintdp[20001],a[101][101],s,n,m;signedmain(){ cin>>s>>n>>m; for(intj=1;j<=s;j++){ for(inti=1;i<=n;i++){ cin>>a[i][j]; } } for(inti=1;......
  • 信息学奥赛初赛天天练-77-NOIP2015普及组-基础题2-二进制、连通图、最小生成树、链表
    NOIP2015普及组基础题24在计算机内部用来传送、存贮、加工处理的数据或指令都是以()形式进行的A二进制码B八进制码C十进制码D智能拼音码5下列说法正确的是()ACPU的主要任务是执行数据运算和程序控制B存储器具有记忆能力,其中信息任何时候都不会......
  • 洛谷P9751 [CSP-J 2023] 旅游巴士
    传送门:P9751[CSP-J2023]旅游巴士为了那个梦我们扬帆起航,为了理所到来的那天跨越无尽黑夜由于这几天做的题目太少,我用小号立下flag:导致果然做了一晚上。。。。并且最后还是没做出来被我妈强制去睡觉了题目意思:题目很明白了,这里说几个要注意的点:道路均只能单向通行到......
  • 洛谷 P3128 [USACO15DEC] Max Flow P
    洛谷P3128[USACO15DEC]MaxFlowP题意给定一棵\(n\)个点的树,给定\(k\)个点对\((u,v)\),把\(u\)到\(v\)路径上所有点的点权加一,最后求最大点权。思路树上差分模版。维护\(a_i\)表示每个点到根的加法标记。对于每个点对\((u,v)\),把\(a_u\),\(a_v\)加一,\(a_{LCA......
  • 洛谷P4163[SCOI2007]排列
    洛谷P4163[SCOI2007]排列题意给一个数字串\(s\)和正整数\(d\),统计\(s\)有多少种不同的排列能被\(d\)整除(可以有前导\(0\))。思路考虑状压dp。\(dp_{S,k}\)表示当前已经选定了\(S\)集合(下标)的数,模\(d=k\)的方案数。状态转移方程:\[dp_{S|2^j,(k\times10+s_j)......
  • 洛谷P10931 闇の連鎖
    洛谷P10931闇の連鎖题意给定一棵\(n\)个点的树,有\(m\)条附加边。第一次删除一条树边,第二次删除一条附加边。求有多少种方案使原来的树不联通。思路考虑求出\(f_i\)表示\(i\)的子树中有多少条附加边连向\(i\)的子树外。若\(f_i=0\),则把\(i\)与\(i\)的父亲之间......
  • 信息学奥赛初赛天天练-76-NOIP2015普及组-基础题1-计算机存储、硬件系统、操作系统、
    NOIP2016普及组基础题111MB等于()A10000字节B1024字节C1000×1000字节D1024×1024字节2在PC机中,PENTIUM(奔腾)、酷睿、赛扬等是指()A生产厂家名称B硬盘的型号CCPU的型号D显示器的型号3操作系统的作用是()A把源程序译成目......
  • 洛谷 P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two
    [USACO2.4]两只塔姆沃斯牛TheTamworthTwo题目描述两只牛逃跑到了森林里。FarmerJohn开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和John)。追击在10×......
  • 洛谷SCP 2024 第一轮(初赛 J 组)模拟题解析(第三部分:完善程序(1-2))
    完善程序一(补全)#include<bits/stdc++.h>usingnamespacestd;constintMAXN=100000;intn;intvis[MAXN],a[MAXN];vector<int>ans;intcheck(intk){intx=n,top=0;for(inti=0;i<=k;i++)vis[i]=0;while(x......