• The Unique MST POJ


    题意:求一个无向图的最小生成树,如果有多个最优解,输出"Not Unique!"

    题解:

      考虑kruskal碰到权值相同的边

      假设点3通过边(1,3)连入当前所维护的并查集s。

      然后有一条边(下图蓝色的边)满足:

          1.长度等于(1,3) 

          2.一端连到3,一端连入S。

      那么该边可以替换掉(1,3)。产生另一颗最小生成树。

     关于如何判断该边一端连3,一端连入S,

    用set来记录S中的点,find判断点是否在集合内。(发现kruskal可以用set写啊

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<string.h>
    #include<set>
    using namespace std;
    const int maxn = 3e4;;set<int> s;
    struct edge {
        int to, from, w;
        edge(int to=0, int from=0, int w=0) :to(to), from(from), w(w) {}
    }e[maxn];
    bool cmp(edge a, edge b) {
        return a.w < b.w;
    }
    int f[maxn];
    int find(int x) {
        return f[x] == x ? x : f[x] = find(f[x]);
    }
    void un(int x, int y) {
        int u = find(x), v= find(y);
        f[u] = v;
    }
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    int main() {
        int t;
        cin >> t;
        while (t--)
        {
            int n, m; cin >> n >> m;
            int num = 0;
            for (int i = 0; i < m; i++) {
                int x, y, z; cin >> x >> y >> z;
                e[num++] = edge(x, y, z);
            }
            for (int i = 1; i <= n; i++)f[i] = i;
            sort(e, e + m,cmp);
            int lastw = -1, lastto = -1, lastfrom = -1,lastv = -1;
            int res=0, flag=0;
            for (int i = 0; i < m; i++) {
    
                if (same(e[i].to, e[i].from)) {
                    if (e[i].w == lastw) {            
                        if (e[i].to == lastv && (s.find(e[i].from) != s.end())) { flag = 1; break; }
                        if (e[i].from == lastv && (s.find(e[i].to) != s.end())) { flag = 1; break; }
                    }
                    continue;
                }
                un(e[i].to, e[i].from);
            res += e[i].w;
    if (s.find(e[i].to) == s.end()) lastv = e[i].to; else lastv = e[i].from; s.insert(e[i].to); s.insert(e[i].from); } if (flag)cout << "Not Unique!"; else cout << res; cout << endl; } }

    队友的玄学代码(改)可以不断记录上一条被选择的边,每次选边时判断一下入度出度关系;

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<string.h>
    using namespace std;
    const int maxn = 3e4;;
    char s[maxn], str[maxn];
    int len1, len2, p[maxn], ans;
    struct edge {
        int to, from, w;
        edge(int to=0, int from=0, int w=0) :to(to), from(from), w(w) {}
    }e[maxn];
    bool cmp(edge a, edge b) {
        return a.w < b.w;
    }
    int f[maxn];
    int find(int x) {
        return f[x] == x ? x : f[x] = find(f[x]);
    }
    void un(int x, int y) {
        int u = find(x), v= find(y);
        f[u] = v;
    }
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    int main() {
        int t;
        cin >> t;
        while (t--)
        {
            int n, m; cin >> n >> m;
            int num = 0;
            for (int i = 0; i < m; i++) {
                int x, y, z; cin >> x >> y >> z;
                e[num++] = edge(x, y, z);
                e[num++] = edge(y, x, z);
            
            }
            for (int i = 1; i <= n; i++)f[i] = i;
            sort(e, e + 2*m,cmp);
            int lastw=-1, lastto=-1, lastfrom=-1;
            int res=0, flag=0;
            for (int i = 0; i < m*2; i++) {
    
                if (same(e[i].to, e[i].from)) {
                    if (e[i].w == lastw) {
                        if ((e[i].from == lastto)&&(e[i].to!=lastfrom)) { flag = 1; break; }
                        if ((e[i].to == lastfrom) && (e[i].from != lastto)) { flag = 1; break; }
                    }
                    continue;
                }
                un(e[i].to, e[i].from);
                res += e[i].w;
                lastto = e[i].to;
                lastw = e[i].w;
                lastfrom = e[i].from;
            }
            if (flag)cout << "Not Unique!";
            else cout << res;
            cout << endl;
        }
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    02
    springmvc根据请求uri获取handlermapping源码
    springmvc零xml配置原理
    maven使用tomcat插件出现Failed to start component [StandardService[Tomcat]]: Failed to start component [StandardEngine[Tomcat]]: A child container failed during startd错误
    zipkin以JAR文件启动以Mysql作为持久化方式
    OAuth2AuthenticationProcessingFilter资源认证服务器过滤器
    OAuth2中四种授权模式以及相应操作
    JVM双亲委派机制
    springcloud对应springboot版本【如果版本依赖不对,则会出现一堆神奇的问题】
    python实现一元二次表达式求值
  • 原文地址:https://www.cnblogs.com/SuuT/p/8762840.html
Copyright © 2020-2023  润新知