WA了2,3两个点,调试了一下午,求求大佬帮帮忙看哪里错了。
查看原帖
WA了2,3两个点,调试了一下午,求求大佬帮帮忙看哪里错了。
630992
djsavu楼主2022/3/13 17:38
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#define RED 0
#define BLACK 1
const int maxn = 2e5;
using namespace std;
int n, m;
struct Edge {
	int next;
	int to;
	int val;
}edge[maxn];
int head[maxn], tot = 0;

void add(int u, int v, int w) {
	edge[++tot].val = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot;
}

queue<int>q;
bool vis[maxn], color[maxn];
bool bfs(int x,int mid) {
	q.push(x);
	color[x] = RED;
	vis[x] = 1;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int i = head[u]; i; i = edge[i].next) {
			int v = edge[i].to;
			if (edge[i].val >= mid) {//忽略权值小于mid的边,看能不能成为二分图
				if (!vis[v]) {
					color[v] = 1 - color[u];
					q.push(v);
					vis[v] = 1;
					//一定要在入队的时候修改vis,不能在出队的时候修改vis,
					//否则当某个元素已经入队但是还没有出队的时候,别的边可能会误访问到这个元素
				}
				else if (vis[v] && color[v] == color[u])
					return false;
				else
					continue;
			}
		}
	}
	return true;
}

bool solve(int mid) {
	for (int i = 1; i <= n; ++i) {
		if (vis[i])
			continue;
		else if (bfs(i, mid))
			continue;
		else
			return false;
	}
	return true;
}


int main() {
	cin >> n >> m;
	int maxW = 0;
	for (int i = 1; i <= m; ++i) {
		int u, v, w;
		cin >> u >> v >> w;
		add(u, v, w);
		add(v, u, w);
		maxW = max(maxW, w);
	}
	int L = 0, R = maxW + 1;
//R要加一是因为我们也需要包含最大的权值边,比如最大的权值是15,此时mid可能最后只能到达14,所以我们要让R=16,从而让mid能够等于15
//我们就要保证mid能够等于15(如果可能的情况下)
//在这种情况下要忽略所有不是权值最大的线段(权值最大的线段可能有很多个),在这种情况下可能原图还是不是二分图,
//就说明最大的仇恨值就是原图最大的线段权值,否则我们在二分的时候就可能忽略这种情况而导致最终的结果不正确。
//总之就是我们要让忽略的权值区间要可以包含所有的权值(当然不一定用得到,但是需要做准备)。
	while (R > L + 1) {
		int mid = (L + R) >> 1;
		if (solve(mid))//如果是二分图就缩小范围
			R = mid;
		else
			L = mid;
		memset(color, 0, sizeof(color));
		memset(vis, 0, sizeof(vis));
		while (!q.empty())
			q.pop();
	}
	cout << L << endl;
	return 0;
}
2022/3/13 17:38
加载中...