二分图判断+二分
给一堆点、边,两两之间有一个值,让分成两个集合,让内部最大边权最小。
排序+二分+二分图判定
存个二分图模板
#include <iostream>#include <functional>#include <algorithm>#include <complex>#include <cstdlib>#include <cstring>#include <fstream>#include <iomanip>#include <sstream>#include <utility>#include <bitset>#include <cctype>#include <cstdio>#include <limits>#include <memory>#include <string>#include <vector>#include <cmath>#include <ctime>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<cstdlib>#include<algorithm>#include<vector>#include<cmath>using namespace std;typedef long long LL;typedef pair<int,int>pii;const int N=2e4+5;const int INF=0x3f3f3f3f;int head[N],tot,n,m;struct Edge{ int u,v,next; bool operator<(const Edge &rhs)const { return next<rhs.next; }} edge[N*10],o[N*5];void add(int u,int v){ edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++;}int cur[N];bool dfs(int u,int f){ cur[u]=(cur[f]^1); for(int i=head[u]; ~i; i=edge[i].next) { int v=edge[i].v; if(v==f||cur[v]==(cur[u]^1))continue; if(cur[v]==cur[u])return false; if(!dfs(v,u))return false; } return true;}bool judge(int x){ Edge tmp; tmp.next=x; int pos=upper_bound(o+1,o+1+m,tmp)-o; if(pos>m)return true; memset(head,-1,sizeof(head)),tot=0; memset(cur,-1,sizeof(cur)); int s; for(int i=pos; i<=m; ++i) add(o[i].u,o[i].v),add(o[i].v,o[i].u),s=o[i].u; for(int i=pos;i<=m;++i){ int s=o[i].u; if(cur[s]!=-1)continue; cur[s]=0; if(!dfs(s,s))return false; } return 1;}int main(){ scanf("%d%d",&n,&m); if(m==0) { printf("0\n"); return 0; } for(int i=1; i<=m; ++i) scanf("%d%d%d",&o[i].u,&o[i].v,&o[i].next); o[0].next=0; sort(o+1,o+1+m); int l=0,r=m; while(l<r) { int mid=(l+r)>>1; if(judge(o[mid].next))r=mid; else l=mid+1; } printf("%d\n",o[(l+r)>>1].next); return 0;}