zoukankan      html  css  js  c++  java
  • codeforces 1250N wires(简单图论)

    传送门

    题意:给定n条边,连接编号从1到1e9之间的点,一次操作可以改变一条边连接的一个端点到另一个端点,也就是将第i条边(u,v)变成(u,w),v≠w,问最少次数操作使得这张图的所有边联通,输出操作次数k,以及每次操作的i,v,w。

    分析:先将点离散化。假设有n个联通块s1,s2....sn,可以将连通块si内一条边端点改成si+1内一个点,但是改变这条边不能使得原有的连通块内的边变得不连通。dfs这个连通块最后一个被访问的边就是满足要求的边。

    代码:

    #include <bits/stdc++.h>
    #define mp make_pair
    #define debug(x) cout << #x << ": " << x << endl
    #define pb push_back
    typedef long long LL;
    const int maxn = 4e5 + 10;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    using namespace std;
    typedef pair<int, int> p;
    p e[maxn], tail[maxn];
    int val[maxn], len = 0, n, t, ord[maxn], vis[maxn], tot = 0, head[maxn], to[maxn], tots;
    vector<int> g[maxn];
    void dfs(int x, int pre) {
        vis[x] = true;
        for (int i = 0; i < g[x].size(); ++i) {
            int v = to[g[x][i]];
            if (!vis[v]) {
                tail[tot] = mp(g[x][i] / 2 + 1, v);
                dfs(v, x);
            }
        }
    }
    int main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cin >> t;
        while (t--) {
            cin >> n;
            len = 0;
            tot = 0;
            tots = 0;
            for (int i = 0; i < n; ++i) {
                cin >> e[i].first >> e[i].second;
                val[len++] = e[i].first;
                val[len++] = e[i].second;
            }
            sort(val, val + len);
            len = unique(val, val + len) - val;
            for (int i = 0; i < len; ++i) {
                vis[i] = 0;
                g[i].clear();
            }
            for (int i = 0; i < n; ++i) {
                int fu = lower_bound(val, val + len, e[i].first) - val;
                ord[fu] = e[i].first;
                e[i].first = fu;
                fu = lower_bound(val, val + len, e[i].second) - val;
                ord[fu] = e[i].second;
                e[i].second = fu;
                to[tots] = e[i].second;
                g[e[i].first].pb(tots++);
                to[tots] = e[i].first;
                g[e[i].second].pb(tots++);
            }
            /*for (int i = 0; i < tots; ++i)
                cout << to[i] << endl;*/
            for (int i = 0; i < len; ++i) {
                if (!vis[i]) {
                    ++tot;
                    head[tot] = i;
                    dfs(i, -1);
                }
            }
            cout << tot - 1 << "
    ";
            for (int i = 1; i < tot; ++i) {
                cout << tail[i].first  << " " << ord[tail[i].second] << " " << ord[head[i + 1]] << "
    ";
            }
        }
    }
  • 相关阅读:
    电子商务测试点总结
    pc 端 测试点总结
    web测试点总结
    Monkey脚本API
    Git 命令
    配置samba的流程
    scrapy使用指南
    链接
    顺序表总结
    python数据类型——字符串类型
  • 原文地址:https://www.cnblogs.com/smallhester/p/11774296.html
Copyright © 2011-2022 走看看