1. 程式人生 > 實用技巧 >洛谷P1525 關押罪犯(二分圖+二分法+思維)

洛谷P1525 關押罪犯(二分圖+二分法+思維)

題目連結:https://www.luogu.com.cn/problem/P1525

題目解法:這個題很不錯,是個思維題。因為換個問法就是,題目要求你問二分圖同組內最大2點間花費。那麼其實一個很不錯的想法就是二分框定mid,我們保證大於mid的邊能構建成二分圖。這個時候就需要去找所謂mid的封頂值了。因為符合線性增大原理,所以可以二分來解決找mid。大概整體意思就是一般圖裡面扣最大二分圖吧。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define
endl '\n' #define eps 0.000000001 #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define IO ios::sync_with_stdio(false);cin.tie(0); using namespace std; const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; const int maxn=1e5+5; int tot,head[maxn]; struct E{ int to,next,w; }edge[maxn
<<1]; void add(int u,int v,int w){ edge[tot].to=v; edge[tot].w=w; edge[tot].next=head[u]; head[u]=tot++; } int n,m; bool bfs(int mid){ queue<int> q;int col[maxn]={0}; rep(i,1,n){ if(!col[i]){ q.push(i);col[i]=1; while(!q.empty()){
int now=q.front();q.pop(); for(int i=head[now];i!=-1;i=edge[i].next){ int v=edge[i].to,w=edge[i].w; if(w>=mid){ if(!col[v]){ col[v]=3-col[now]; q.push(v); } else if(col[v]==col[now]){ return false; } } } } } } return true; } int main(){ cin>>n>>m;mem(head,-1); int L=0,R=0; rep(i,1,m){ int u,v,w;cin>>u>>v>>w; R=max(R,w); add(u,v,w);add(v,u,w); } while(R>L){ int mid=(L+R)>>1; if(bfs(mid)) R=mid; else L=mid+1; } if(L-1>=0)cout<<L-1<<endl; else puts("0"); }
View Code