[洛谷P1396]营救
题目大意:给你一个有向图,让你找到一条S->T的路径是的该路径上最大值最小
题解:因为是求最小的最大值,很容易想到二分答案,我们可以二分这个最大值,然后进行判断,用并查集维护,把所有路径中小于等于该值的路径的两头合并,最后判断如果S和T的父亲相同就是合法的解,记录一下,最后输出答案
C++ Code:
#include<cstdio> #include<algorithm> using namespace std; const int maxn=10100; int n,m,S,T,ans; int f[maxn]; int cnt; struct Edge{ int from,to,cost; }e[maxn<<1]; inline bool cmp(Edge a,Edge b){return a.cost<b.cost;} void add(int a,int b,int c){ e[++cnt]=(Edge){a,b,c}; } int find(int x){return (x==f[x]?x:(f[x]=find(f[x])));} bool check(int mid){ for (int i=1;i<=n;i++)f[i]=i; for (int i=1;i<=m;i++){ if (e[i].cost>mid)return (find(f[S])==find(f[T])); int x=find(f[e[i].from]),y=find(f[e[i].to]); f[x]=f[y]; if (f[S]==f[T])return true; } return (find(f[S])==find(f[T])); } int main(){ scanf("%d%d%d%d",&n,&m,&S,&T); for (int i=0;i<m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } sort(e+1,e+m+1,cmp); int l=0,r=100000000; while(l<=r){ int mid=l+r>>1; if (check(mid)){ ans=mid; r=mid-1; }else l=mid+1; } printf("%d\n",ans); return 0; }