• POJ 1679 The Unique MST


    POJ_1679

        这个题目可以先用prim求一棵最小生成树,然后顺便更新出书上两点间的最大边权。

        之后枚举每一条边,如果这条边没有在生成树上,且生成树上这两点间的最大边权与之相等,那么就说明这条边也可以作为最小生成树边,因此最小生成树就不唯一了。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 110
    #define MAXM 100010
    #define INF 0x3f3f3f3f
    int N, M, first[MAXD], e, next[MAXM], v[MAXM], dis[MAXD], pre[MAXD], vis[MAXD], g[MAXD][MAXD], max[MAXD][MAXD];
    void init()
    {
        int i, x, y, z;
        scanf("%d%d", &N, &M);
        memset(g, 0x3f, sizeof(g));
        for(i = 0; i < M; i ++)
        {
            scanf("%d%d%d", &x, &y, &z);
            g[x][y] = g[y][x] = z;
        }
    }
    void add(int x, int y)
    {
        v[e] = y;
        next[e] = first[x], first[x] = e ++;
    }
    void dfs(int cur, int fa, int k, int m)
    {
        int i;
        max[cur][k] = max[k][cur] = m;
        for(i = first[cur]; i != -1; i = next[i])
            if(v[i] != fa)
                dfs(v[i], cur, k, m > max[cur][v[i]] ? m : max[cur][v[i]]);
    }
    int intree(int x, int y)
    {
        int i;
        for(i = first[x]; i != -1; i = next[i])
            if(v[i] == y)
                return 1;
        return 0;
    }
    int isunique()
    {
        int i, j, k;
        for(i = 1; i <= N; i ++)
            for(j = i + 1; j <= N; j ++)
                if(g[i][j] != INF && !intree(i, j) && g[i][j] == max[i][j])
                    return 0;
        return 1;
    }
    void solve()
    {
        int i, j, k, m, ans = 0;
        memset(first, -1, sizeof(first));
        e = 0;
        memset(dis, 0x3f, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        dis[1] = 0, vis[1] = 1;
        for(i = 2; i <= N; i ++)
            if(g[1][i] < dis[i])
                dis[i] = g[1][i], pre[i] = 1;
        for(i = 1; i < N; i ++)
        {
            m = INF;
            for(j = 1; j <= N; j ++)
                if(!vis[j] && dis[j] < m)
                    m = dis[k = j];
            ans += m, vis[k] = 1;
            for(j = 1; j <= N; j ++)
                if(!vis[j] && g[k][j] < dis[j])
                    dis[j] = g[k][j], pre[j] = k;
            add(pre[k], k), add(k, pre[k]);
            dfs(pre[k], k, k, m);
        }
        if(isunique())
            printf("%d\n", ans);
        else
            printf("Not Unique!\n");
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    2021年-组装ITX台式机电脑
    jetbrain idea误删文件的两种恢复的方法
    Jmeter Macbook上利用命令行ssh tunnel 开启mysql链接
    pipeline buildResult 和 stageResult的区别
    Jenkins Pipeline ample 样板
    docker删除镜像
    C++内存分区
    auto | auto& | auto&&
    一种简易的音频信号延迟测量方案
    自制一个简易的任意音频信号发生器
  • 原文地址:https://www.cnblogs.com/staginner/p/2514695.html
Copyright © 2020-2023  润新知