为什么?关于二分的问题
查看原帖
为什么?关于二分的问题
188970
Twiter_ln楼主2023/11/1 20:45

对于 二分答案二分答案 的 解法来说:

while(l < r) {
	mid = (l + r) >> 1;
	if(check()) r = mid - 1, ans = mid;
	else l = mid + 1;
}

这份交上去 60pts60pts 。

而改成 下面↓下面↓ 这样后,

if(mid==r) mid--;
if(check()) r = mid, ans = mid;

满了^_^

哪位大佬能解释下为什么?

源代码如下:

#include<iostream> // P1525 [NOIP2010 Ìá¸ß×é] ¹ØÑº×ï·¸
#include<cstdio> // 2e4 1e5 
#include<cstring>
#include<vector>
#define N 200037

using namespace std;

int n, m, x, y;
int fa[N];
int l, r, mid, ans;
vector <int> e[N];

struct pot{
	int u, v;
	int val;
}E[5*N];

inline bool cmp(pot x, pot y) {
	return x.val > y.val;
}

int vis[N];

bool p;
inline void dfs(int u, int color) {
	int v;
	for(int i=0;i<e[u].size();++i) {
		v = e[u][i];
		if(vis[v]) {
			if(vis[v] + vis[u] != 3) {
				p = true;
				return ;
			}
			continue;
		}
		vis[v] = 3 - color;
		dfs(v, vis[v]);
		if(p) return ;
	}
}
inline bool check() {
	int pos;
	for(int i=1;i<=n;++i) e[i].clear();
	for(int i=1;i<=m;++i) {
		if(E[i].val >= mid) {
			e[E[i].u].push_back(E[i].v);
			e[E[i].v].push_back(E[i].u);
		}
	}
	memset(vis, 0, sizeof(vis));
	
	for(int i=1;i<=n;++i) {
		if(!vis[i]) {
			p = false;
			vis[i] = 1; // Õâ¶ù±¾À´ tm дµÄ E[i].u
			dfs(i, 1); // Õâ¶ùÒ²ÊÇ 
			if(p) return false;
		}
	}
}

int main() {
	
//	freopen("P1525_2.in","r",stdin);
	
	scanf("%d%d", &n, &m);
	for(int i=1;i<=n;++i) fa[i] = i;
	for(int i=1;i<=m;++i) scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].val);
	
	l = 1, r = 1e9;
	while(l < r) {
		mid = (l + r) >> 1;
//		if(mid==r) mid--;
		if(check()) r = mid - 1, ans = mid;
		else l = mid + 1;
	}
	
//	printf("%d\n", ans);
	
	int maxx = -2;
	for(int i=1;i<=m;++i) {
		if(E[i].val >= ans) continue;
		maxx = max(maxx, E[i].val);
	}
	if(maxx<0) maxx=0;
	printf("%d\n", maxx);
	
	return 0;
}
/*

4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
: 3512

*/
2023/11/1 20:45
加载中...