首页 > 其他分享 >P1525 NOIP2010 提高组 关押罪犯 题解

P1525 NOIP2010 提高组 关押罪犯 题解

时间:2024-11-08 17:00:40浏览次数:3  
标签:P1525 二分 影响力 NOIP2010 int 题解 罪犯 答案

Link: P1525 NOIP2010 提高组 关押罪犯 - 洛谷

分析

首先题目给出了罪犯与罪犯之间的矛盾关系,这让我们可以想到图或并查集。然后,题目又说了要把罪犯分入两个监狱,也就是把罪犯看作点,要把这些点分入两个集合,这很自然地可以想到二分图。再然后,市长只会去看列表中的第一个事件的影响力,而我们希望这个影响力最大的事件影响最小,所以又可以想到用二分来寻找答案。

到这个地步,做这道题的要素已经集齐,我们继续分析具体怎么做。首先我们通过二分来枚举最大影响力,然后考虑如何判断是否合法。既然我们希望会造成大影响的罪犯尽量被分在两个监狱里,那么我们可以在通过染色判定二分图的时候加一个条件,即只有边权大于等于当前枚举的最大影响力时,我们才考虑将两个罪犯放在不同监狱里面(学过二分图应该看得懂这句话)。在这个限制下,如果染色完二分图合法,那么我们就接着尝试检测更小的答案;否则,说明当前答案过小,导致影响力大于等于当前答案的所有罪犯不能被正确地分入两个监狱,接下来要尝试更大检测更大的答案。

注意二分答案的写法,比较奇特 反正我没见过,是我练得还太少了

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 20005;
const int maxm = 100005;
int n, m;
int head[maxn];
struct Edge {
	int to, next, weight;
} edge[maxm << 1];

inline void insertEdge(int u, int v, int w) {
	static int edgecnt;
	edge[++edgecnt].to = v;
	edge[edgecnt].weight = w;
	edge[edgecnt].next = head[u];
	head[u] = edgecnt;
}

int color[maxn];
bool dfs(int u, int col, int anger) {
	color[u] = col;
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to, w = edge[i].weight;
		if (w < anger) continue;
		if (!color[v]) {
			if (!dfs(v, 3 - col, anger)) return false;
		} else if (color[u] == color[v]) return false;
	}
	return true;
}

inline bool check(int anger) {
	memset(color, 0, sizeof(color));
	for (int i = 1; i <= n; i++) {
		if (!color[i]) {
			if (!dfs(i, 1, anger)) return false;
		}
	}
	return true;
}

int main() {
	scanf("%d%d", &n, &m);
	int l = 0, r = 0;
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		insertEdge(u, v, w);
		insertEdge(v, u, w);
		r = max(r, w);
	}
	while (l + 1 < r) {
		int mid = (l + r) >> 1;
		if (check(mid)) r = mid;
		else l = mid;
	}
	printf("%d", l);
	return 0;
}

标签:P1525,二分,影响力,NOIP2010,int,题解,罪犯,答案
From: https://www.cnblogs.com/jxyanglinus/p/18535425

相关文章

  • 题解
    最近模拟赛抽象题太多了,让他们聚一聚T1多校A层冲刺NOIP2024模拟赛18T3DBA暴力比较显然,直接数位dp就好,记搜的复杂度是\(O(n^4)\)的,用递推加前缀和优化可以优化为\(O(n^3)\),但我还是不理解\(O(n^3)\)凭啥能\(拿97pts\),虽然和正解没啥关系,但还是放一下记搜的代码:点击查看代码......
  • CF1995 题解
    B有n种物品,每种物品价格为$a_i$,数量为$c_i$。要求选取物品的方案,满足价格极差不超过1,价格总和不超过m。最大化价格总和。$n\le10^5,m\le10^{18},a_i,c_i\le10^9,a_i\neqa_j$显然只有\(x\)和\(x,x+1\)两种选择情况。\(x\)直接贪心选即可,考虑\(x,x+1\)。发......
  • ICPC23沈阳区域赛 D. Dark LaTeX vs. Light LaTeX 题解
    D.DarkLaTeXvs.LightLaTeXThe2023ICPCAsiaShenyangRegionalContest(The2ndUniversalCup.Stage13:Shenyang)给两个字符串\(s,t\),长度分别为\(n,m\),现在分别取\(s,t\)的子串\(s',t'\),合成一个新的长度为偶数的字符串\(str=s'+t'\),记\(str\)的长度为......
  • 题解:P11249 [GESP202409 七级] 小杨寻宝
    题目显然等价于问所有宝箱是否在一条链上。稍微转化一下题意,即我们现在要找到一条链,使得这条链上有宝物的节点数量尽可能多。想到这里我们发现这个和树的直径比较相似,那么我们直接大胆将深度定义为从根到这个节点上有宝箱节点的数量,然后做一遍树的直径。最后判断直径长度是否等......
  • 题解:3254. 长度为 K 的子数组的能量值
    Problem:3254.长度为K的子数组的能量值I题解:3254.长度为K的子数组的能量值给定一个数组nums和一个整数k,我们需要找出所有长度为k的子数组的“能量值”。根据题意:如果子数组是连续递增的,能量值等于子数组中的最大元素。否则,能量值为-1。以下是两种不同......
  • CF 1365 题解
    CF1365题解AMatrixGame注意到每次操作都相当于会损失一行和一列,那么最多进行可用行列较少的那一个的轮数.判断奇偶性即可,BTroubleSort手玩发现,不管一个属性的元素集合内部多么无序,都可以借助一个其它属性的元素达到有序.归纳证明特别简单.因此,一个序列可以......
  • P5479 [BJOI2015] 隐身术 题解
    题目传送门前置知识后缀数组简介|字符串哈希|二分解法考虑分别计算出编辑距离恰好等于\(k_{0}\in[0,k]\)的答案。观察在编辑距离的存在下,长度差至多为\(k\)。考虑设\(f_{i,j}\)表示最大的\(x\)使得\(s_{1\simx}\)和\(t_{1\simx+j}\)可以在\(i\)次编......
  • P7984 [USACO21DEC] Tickets P 题解
    题目传送门前置知识线段树优化建图|最短路解法考虑对票建虚点,从\(c_{i}\)向\(i+n\)连一条权值为\(p_{i}\)的边,然后从\(i+n\)向\([a_{i},b_{i}]\)连一条权值为\(0\)的边。建出反图后\(1\toi\)和\(n\toi\)的路径集合会有重复统计的部分,不妨以\(dis_{1,i......
  • 快速上手Docker部署Flask项目 附常见问题解决
    一、准备Flask项目1.项目结构有一个app.py文件作为主应用程序入口,内容示例:fromflaskimportFlaskapp=Flask(__name__)@app.route('/')defhello_world():return'Hello,World!'if__name__=='__main__':app.run(host='0.0.0.0&#......
  • P9192 [USACO23OPEN] Pareidolia P 题解
    P9192[USACO23OPEN]PareidoliaP题解首先自然考虑不带修的情况。考虑问题的本质就是求序列中尽量短的bessie序列个数。对于尽量短的理解是对于bessiebessie序列,不考虑其由\(1,8\sim12\)构成的序列,只考虑\(1\sim6,7\sim12\)组成的序列。于是考虑dp:设\(dp_{i......