zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接

    题目大意

      给你一张图,图里有很多连通块,你可以将一条边中的一个点去掉连到另外一个点上,问你将整张图变成连通图的最小代价。

    解题思路

      我们如果要使两个连通块相连的话,去掉的那个点一定不能是割点,所以每次连接的时候去掉一个连通块上不是割点的点,然后让其和另一个连通块上的任意一个点相连就行了。如果一个点是割点的话,按dfs的访问顺序必定不是最后访问的那个点,所以说我们只要求出每个连通块最后访问的那个点以及对应的边就行了。

    代码

    const int maxn = 2e5+10;
    struct E {
        int to, nxt;
    } e[maxn<<1];
    P eg[maxn];
    int h[maxn], tot, n, m, vec[maxn];
    int vis[maxn], lst1[maxn], lst2[maxn], tot2;
    void add(int u, int v) {
        e[++tot] = {v, h[u]};
        h[u] = tot;
    }
    int find(int x) {
        return lower_bound(vec+1, vec+n+1, x)-vec;
    }
    void dfs(int u) {
        lst1[tot2] = u; vis[u] = 1;
        for (int i = h[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (vis[v]) continue;
            //cout << i << ' ' << tot2 << endl;
            lst2[tot2] = i;
            dfs(v);
        } 
    }
    struct I {
        int id, u, v;
    };
    int main() {
        int __; cin >> __;
        while(__--) {
            cin >> m; n = tot = tot2 = 0;
            for (int i = 1, a, b; i<=m; ++i) {
                scanf("%d%d", &a, &b);
                eg[i] = {a, b};
                vec[++n] = a, vec[++n] = b;
            }
            sort(vec+1, vec+n+1);
            n = unique(vec+1, vec+n+1)-vec-1;
            for (int i = 1; i<=m; ++i) {
                int u = find(eg[i].first);
                int v = find(eg[i].second);
                add(u, v); add(v, u);
            }
            for (int i = 1; i<=n; ++i)
                if (!vis[i]) ++tot2, dfs(i);
            vector<I> ans;
            //cout << tot2 << endl;
            for (int i = 2; i<=tot2; ++i) ans.push_back({lst2[i], lst1[i], lst1[1]});
            cout << ans.size() << endl;
            for (auto v : ans) printf("%d %d %d
    ", (v.id+1)/2, vec[v.u], vec[v.v]);
            for (int i = 0; i<=n; ++i) h[i] = vis[i] = lst1[i] = lst2[i] = 0; 
        }
        return 0;
    }
    
  • 相关阅读:
    数据结构之查找算法总结笔记
    html的a链接的href怎样才另起一个页面
    深入理解CSS中的空白符和换行
    CSS文本方向
    alert()与console.log()的区别
    CSS旧版flex及兼容
    Java:类与继承
    Java中只有按值传递,没有按引用传递!
    String作为方法参数传递 与 引用传递
    Java:按值传递还是按引用传递详细解说
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14488210.html
Copyright © 2011-2022 走看看