Ural1709-Penguin-Avia

来源:互联网 发布:餐饮收银软件排行 编辑:程序博客网 时间:2024/05/29 13:14

用并查集先筛选掉以及连通的边,然后再将未连通边加上即可。

#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn = 100 + 5;char mat[maxn][maxn];char ans[maxn][maxn];struct edge {    int u, v;};vector<edge> e;int par[maxn];int rk[maxn];void init(int n) {    for (int i = 0; i < n; i++) {        par[i] = i;        rk[i] = 0;    }}int find(int x) {    if (par[x] == x) {        return x;    } else {        return par[x] = find(par[x]);    }}void unite(int x, int y) {    x = find(x);    y = find(y);    if (x == y) {        return;    }    if (rk[x] < rk[y]) {        par[x] = y;    } else {        par[y] = x;        if (rk[x] == rk[y]) {            rk[x]++;        }    }}bool same(int u, int v) {    return find(u) == find(v);}int main(int argc, char const *argv[]) {    int n, d, a;    scanf("%d%d%d", &n, &d, &a);    for (int i = 0; i < n; i++) {        getchar();        for (int j = 0; j < n; j++) {            scanf("%c", &mat[i][j]);        }    }    for (int i = 0; i < n; i++) {        for (int j = i; j < n; j++) {            if (mat[i][j] == '1') {                e.push_back((edge){i, j});            }        }    }    init(n);    long long cost = 0;    memset(ans, '0', sizeof(ans));    for (int i = 0; i < e.size(); i++) {        int u = e[i].u;        int v = e[i].v;        if (!same(u, v)) {            unite(u, v);        } else {            ans[u][v] = 'd';            ans[v][u] = 'd';            cost += d;        }    }    for (int i = 0; i < n; i++) {        for (int j = i; j < n; j++) {            if (!same(i, j)) {                unite(i, j);                ans[i][j] = 'a';                ans[j][i] = 'a';                cost += a;            }        }    }    printf("%lld\n", cost);    for (int i = 0; i < n; i++) {        for (int j = 0; j < n; j++) {            putchar(ans[i][j]);        }        putchar('\n');    }    return 0;}
0 0
原创粉丝点击