k-City

city

题意:

n个点m条边,有q次询问每次给当一个p,当两个点之间的边权小于p时,这条边就会被摧毁掉,问每次给定p的时候有多少对点相互连通;

思路:

每次查询,都要遍历一遍所有的点,判断这条边是否大于p,时间复杂度远不够,假设p1<p2,当一条边大于p2的时候一定大于p1,所以可以由大到小做,这样省掉了许多判断的时间,维护连通块的节点个数可以直接使用并查集

题解:

#include <bits/stdc++.h>
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(0);
#define lowbit(x) x&(-x)
#define INF 0x7fffffff
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);};
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int N = 2000010;
struct edge {
    int u, v, w;
    bool operator <(const edge& t) const {
        return w > t.w;
    }
} E[N];
struct query {
    int power, id;
    bool operator <(const query& t) const {
        return power > t.power;
    }
} Q[N];
int s[N], p[N], ans[N];
int find(int x) {
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}
void solve() {
    int n, m, q;
    cin >> n >> m >> q;
    int u, v, w;
    for (int i = 1; i <= n; i++) p[i] = i, s[i] = 1;
    for (int i = 1; i <= m; i++) {
        cin >> u >> v >> w;
        E[i] = {u, v, w};
    }
    for (int i = 1; i <= q; i++) {
        cin >> w;
        Q[i] = {w, i};
        ans[i] = 0;
    }
    sort(E + 1, E + 1 + m);
    sort(Q + 1, Q + 1 + q);
    int cur = 1;
    int sum = 0;
    for (int i = 1; i <= q; i++) {
        while (E[cur].w >= Q[i].power and cur <= m) {
            if (cur > m) break;
            int u=E[cur].u,v=E[cur].v;
            int pa = find(u);
            int pb = find(v);
            if (pa != pb) {
                sum += s[pa] * s[pb];

                p[pa] = pb;
                s[pb] += s[pa];
            }
            cur++;
        }
        ans[Q[i].id] = sum;

    }
    for (int i = 1; i <= q; i++) cout << ans[i] << endl;
}
signed main() {
    IOS;
    int _;  while (cin >> _) {while (_--)solve();}
    return 0;
}
posted @ 2021-10-05 23:03  指引盗寇入太行  阅读(61)  评论(0编辑  收藏  举报