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; }