题目链接:https://www.luogu.com.cn/problem/P1525
解法一:并查集
按照w排序,看每一对u、v,如果两个在同一个并查集中,那么输出w,即为最大。
如果不在:当u还没有敌人时,则敌人为v;如果有敌人,那么u原来的敌人e[u]和现在敌人v为一个并查集。同理。
AC代码:

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=100005; 7 int n,m; 8 int f[N],e[N]; 9 struct node{ 10 int u,v,w; 11 }q[N]; 12 bool cmp(node a,node b){ 13 return a.w>b.w; 14 } 15 int find(int x){ 16 if(f[x]!=x) f[x]=find(f[x]); 17 return f[x]; 18 } 19 int main(){ 20 scanf("%d%d",&n,&m); 21 for(int i=1;i<=m;i++) 22 scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w); 23 sort(q+1,q+m+1,cmp); 24 for(int i=1;i<=n;i++) f[i]=i; 25 for(int i=1;i<=m;i++){ 26 int u=q[i].u,v=q[i].v; 27 int r1=find(u),r2=find(v); 28 if(r1==r2) {printf("%d",q[i].w); return 0;} 29 if(!e[u]) e[u]=v; 30 else f[find(e[u])]=find(v); 31 if(!e[v]) e[v]=u; 32 else f[find(e[v])]=find(u); 33 } 34 printf("0"); 35 return 0; 36 }
解法二:二分图判定+二分答案
因为题目求的是最大值最小,所以可以用二分答案。二分这个答案,然后将大于等于这个二分的答案的边的两边的点进行染色,看是否是二分图。(自己的二分答案写的好奇葩
AC代码:

1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 const int N=100005; 7 int n,m,tot; 8 int head[N],color[N]; 9 struct node{ 10 int to,next,w; 11 }edge[N<<1]; 12 void init(){ 13 memset(head,-1,sizeof(head)); 14 } 15 void add(int u,int v,int w){ 16 edge[tot].to=v; 17 edge[tot].next=head[u]; 18 edge[tot].w=w; 19 head[u]=tot++; 20 } 21 bool work(int x){ 22 queue<int> q; 23 memset(color,0,sizeof(color)); 24 for(int i=1;i<=n;i++){ 25 if(!color[i]){ 26 q.push(i); 27 color[i]=1; 28 while(!q.empty()){ 29 int u=q.front(); q.pop(); 30 for(int i=head[u];i!=-1;i=edge[i].next){ 31 int v=edge[i].to; 32 if(edge[i].w>=x){ 33 if(!color[v]){ 34 q.push(v); 35 if(color[u]==1) color[v]=2; 36 else color[v]=1; 37 } 38 else if(color[v]==color[u]) return 0; 39 } 40 } 41 } 42 } 43 } 44 return 1; 45 } 46 int main(){ 47 init(); 48 int l=0,r=0,ans=0; 49 scanf("%d%d",&n,&m); 50 for(int i=1;i<=m;i++){ 51 int u,v,w; 52 scanf("%d%d%d",&u,&v,&w); 53 r=max(r,w); 54 add(u,v,w); add(v,u,w); 55 } 56 r++; 57 while(l<=r){ 58 int m=(l+r)>>1; 59 if(work(m)) {ans=m; r=m-1;} 60 else l=m+1; 61 } 62 if(ans==0) {printf("0"); return 0;} 63 else printf("%d",ans-1); 64 return 0; 65 }