对于 二分答案 的 解法来说:
while(l < r) {
mid = (l + r) >> 1;
if(check()) r = mid - 1, ans = mid;
else l = mid + 1;
}
这份交上去 60pts 。
而改成 下面↓ 这样后,
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
*/