b_lg_繁忙的都市(二分边权 / 最小生成树)

城市中每条道路都有一个分值,分值越小表示这个道路越繁忙,越需要进行改造。
但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的要求:
1.改造的那些道路能够把所有的交叉路口直接或间接的连通起来。
2.在满足要求1的情况下,改造的道路尽量少。
3.在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。

输出:选出了几条道路,分值最大的那条道路的分值是多少。

方法一:二分最大边权

叫你去掉几条边权较大的边,使得总边权最小,且保持图仍然连通(最小生成树的题),可以用二分枚举一个边权,判断用当前边权下能否遍历完剩下的结点(相当于去掉了一些边)

#include<bits/stdc++.h>
using namespace std;
const int N=305;
struct node {
    int u,w;
};
vector<node> g[N];
int n,m,st[N];
void dfs(int u, int maxw) {
    st[u]=1;
    for (auto& to : g[u]) {
        int v=to.u, w=to.w;
        if (st[v] || w>maxw) continue;
        dfs(v,maxw);
    }
}
bool vis_all(int w) {
    memset(st,false,sizeof st);
    dfs(1,w);
    for (int i=1; i<=n; i++) if (!st[i])
        return false;
    return true;
}
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>m;
    for (int i=0; i<m; i++) {
        int u,v,w; cin>>u>>v>>w;
        g[u].push_back({v,w});
        g[v].push_back({u,w});
    }
    int l=1, r=1e5+5;
    while (l<r) {
        int w=l+r>>1;
        if (vis_all(w)) r=w;
        else l=w+1;
    }
    cout<<n-1<<' '<<l<<'\n';
    return 0;
}   

一模一样的题:https://www.luogu.com.cn/problem/P1396

posted @ 2020-10-08 21:19  童年の波鞋  阅读(91)  评论(0编辑  收藏  举报