题目描述
题解
这道题我们可以二分枚举这个影响力,显然影响力越小,越不容易满足,且具有单调性。
我们发现当一个二分值合法,必定满足大于这个数的怨气值不能够存在,而小于或等于的存在或不存在均可。因此我们可以将大于的连接一条边,那么如果要分成两组,则连接的两条边要在不同的组内,因此这就是一张二分图。
只要我们对每一个边权大于 m i d mid mid的边连接一条边,用染色法判定是否为二分图即可。
时间复杂度: O ( n l o g n ) O(n\ log\ n) O(n log n)
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000000;
int n, m, flag;
int x[N], y[N], v[N], c[N];
vector <int> a[N];
void dfs(int x,int col)
{
if (flag == 1) return;
c[x] = col;
for (int i=0;i<a[x].size();++i)
{
int y = a[x][i];
if (c[y] == 0) dfs(y,3-col);
else if (c[x] == c[y]) flag = 1;
}
return;
}
bool check(int mid)
{
flag = 0;
for (int i=1;i<=n;++i)
a[i].clear(), c[i] = 0;
for (int i=1;i<=m;++i)
if (v[i] > mid) {
a[x[i]].push_back(y[i]);
a[y[i]].push_back(x[i]);
}
for (int i=1;i<=n;++i)
if (c[i] == 0) dfs(i,1);
return flag^1;
}
int main(void)
{
scanf("%d %d", &n, &m);
for (int i=1;i<=m;++i)
scanf("%d %d %d", x+i, y+i, v+i);
int l = 0, r = 1e9;
while (l+1 < r)
{
int mid = l+r >> 1;
if (check(mid)) r = mid;
else l = mid;
}
if (check(l)) cout<<l<<endl;
else cout<<r<<endl;
return 0;
}