P1396 营救 图方面的二分
题意:给出一个n个点,m条边的图,每条边有一个拥挤度
让我们从s走到t,使最大的拥挤度最小
思路:每一次遍历图的复杂度为n,二分遍历的复杂度即为(n*logn)
我们定一个L R的边界
然后check,每一次check便是一次遍历,每次遍历假如能够在某个拥挤度之下走到终点,则满足,反之不满足
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=5e4+10; 4 int s,t; 5 struct node 6 { 7 int v,w; 8 int nxt; 9 }G[maxn]; int head[maxn]; int num; 10 int flag; 11 void add(int u,int v,int w) 12 { 13 G[++num].v=v;G[num].w=w;G[num].nxt=head[u];head[u]=num; 14 } 15 void dfs(int u,int fa,int limit) 16 { 17 if(flag) return; 18 if(u==t){ 19 flag=1; 20 return; 21 } 22 for(int i=head[u];i;i=G[i].nxt){ 23 int v=G[i].v;int w=G[i].w; 24 if(v==fa) continue; 25 if(w>limit) continue; 26 dfs(v,u,limit); 27 } 28 } 29 int check(int mid) 30 { 31 flag=0; 32 dfs(s,0,mid); 33 if(flag) return 1; 34 else return 0; 35 } 36 int main() 37 { 38 int n,m; 39 scanf("%d%d%d%d",&n,&m,&s,&t); 40 for(int i=1;i<=m;i++){ 41 int u,v,w; 42 scanf("%d%d%d",&u,&v,&w); 43 add(u,v,w); 44 add(v,u,w); 45 } 46 int L=1;int R=1e4; 47 int ans; 48 while(L<=R){ 49 // printf("ans:%d\n",ans); 50 int mid=L+R>>1; 51 if(check(mid)){ 52 ans=mid; 53 R=mid-1; 54 } 55 else{ 56 L=mid+1; 57 } 58 } 59 printf("%d\n",ans); 60 return 0; 61 }