美文网首页
PAT顶级 || 1001 Battle Over Cities

PAT顶级 || 1001 Battle Over Cities

作者: zilla | 来源:发表于2019-12-27 02:24 被阅读0次

    1001 Battle Over Cities - Hard Version (35分)

    这个时间我爱了嘻嘻

    思路:最小生成树MST

    • Kruskal算法:取不形成环的最短边的集合。
      不形成环这点用并查集来保证。

    • in use的边权值直接看成0,destroyed的边权值为cost,边全部输入完后排序一次。

    • 删去一个点和与之相连的边,求剩下的点的MST,找删去后MST总边权最大的点。

    • ⚠️删去某点后不存在MST的情况

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    
    #define INF 0x3fffffff
    using namespace std;
    
    // kruskal MST
    struct Road {
        int cost, v1, v2;
    
        bool operator<(const Road &r2) const {
            if (cost != r2.cost) return cost < r2.cost;
            return make_pair(v1, v2) < make_pair(r2.v1, r2.v2);
        }
    };
    
    int nn, mm;
    int graph[501][501], uf[501];
    
    int find_(int sn) {
        return uf[sn] < 0 ? sn : uf[sn] = find_(uf[sn]);
    }
    
    void union_(int a, int b) {
        a = find_(a);
        b = find_(b);
        int M = max(a, b), m = min(a, b);
        if (M != m) {
            uf[m] += uf[M];
            uf[M] = m;
        }
    }
    
    vector<int> res;
    vector <Road> edges;
    int mmax = -1;
    
    void MST(int del_v) {
        fill(uf, uf + 501, -1);
        int ind = 0, cnt = 0, total = 0;
        for (; ind < mm && cnt < nn - 2; ind++) {
            if (edges[ind].v1 != del_v && edges[ind].v2 != del_v) {
                int v1 = edges[ind].v1, v2 = edges[ind].v2;
                if (find_(v1) != find_(v2)) {
                    union_(v1, v2);
                    total += edges[ind].cost;
                    cnt++;
                }
            }
        }
        if (cnt == nn - 2) {
            if (total == mmax) res.emplace_back(del_v);
            else if (total > mmax) {
                mmax = total;
                res.clear();
                res.emplace_back(del_v);
            }
        } else {
            if (mmax != INF) {
                res.clear();
                mmax = INF;
            }
            res.emplace_back(del_v);
        }
    }
    
    int main() {
        scanf("%d%d", &nn, &mm);
        for (int i = 0; i < mm; ++i) {
            int v1, v2, cost, st;
            scanf("%d%d%d%d", &v1, &v2, &cost, &st);
            if (st) cost = 0;
            edges.emplace_back(Road{cost, min(v1, v2), max(v1, v2)});
        }
        sort(edges.begin(), edges.end());
        for (int i = 1; i <= nn; i++) {
            MST(i);
        }
        if (mmax) {
            int i = 0;
            for (; i < res.size() - 1; i++) printf("%d ", res[i]);
            printf("%d\n", res[i]);
        } else puts("0");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:PAT顶级 || 1001 Battle Over Cities

          本文链接:https://www.haomeiwen.com/subject/nhmhoctx.html