bzoj1083: [SCOI2005]繁忙的都市

二分分值最大值lid,把所有的分值小于lid的边加入,如果图联通,证明可以。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100000 + 10;
const int maxm = 200000 + 10;

int h[maxn],p = -1;
int n,m,l,r,lid;
int v[maxm],next[maxm],dist[maxm];
int q[maxn];
bool vis[maxn];

void add(int a,int b,int d) { 
  v[++p] = b; dist[p] = d; next[p] = h[a]; h[a] = p;
  v[++p] = a; dist[p] = d; next[p] = h[b]; h[b] = p;
}

int bfs() {
  memset(vis,0,sizeof(vis));
  int l = 0,r = 0,res = 1;
  
  vis[q[r++] = 1] = 1;
  while(l < r) {
    int u = q[l++];
    for(int i = h[u]; ~i; i = next[i]) 
      if(lid >= dist[i] && !vis[v[i]]) {
        vis[q[r++] = v[i]] = 1;  
        res++;
      }
  }
  return res;
}

int main() {
  memset(h,-1,sizeof(h));
  scanf("%d%d",&n,&m);
  l = 1, r = 0;
  for(int i = 1,a,b,c; i <= m; i++) {
    scanf("%d%d%d",&a,&b,&c);
    add(a,b,c);
    r = max(r,c);
  }
  
  while(l < r) {
    lid = (l+r) >> 1;
    if(bfs() == n) r = lid;
    else l = lid+1;
  }
  printf("%d %d\n",n-1,l);
  return 0; 
}
posted @ 2016-04-11 21:14  invoid  阅读(175)  评论(0编辑  收藏  举报