zoukankan      html  css  js  c++  java
  • poj1679 The Unique MST

    这题只是简单的最小生成树的一个变形。 可以用kruskal 先进行求最小生成树, 然后, 用dp 记录每一个点之间的最大长度。 然后枚举每一条边(未在最小生成树中的), 如果发现有和最小生成树中的边的最大相等的就返回不唯一, 否则如果都大的话, 返回唯一

    View Code
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define maxn 102
    using namespace std;
    
    struct node
    {
        int left, right, val;
    }map[maxn* maxn], edge[maxn * maxn];
    
    int e[maxn][maxn];
    int map_count;
    int parent[maxn];
    int n, m, sum;
    int edge_min[maxn][maxn];
    int fleft, fright, fval;
    
    void add(int left, int right)
    {
        edge_min[left][0] ++;
        edge_min[left][edge_min[left][0]] = right;
        edge_min[right][0] ++;
        edge_min[right][edge_min[right][0]] = left;
    }
    
    void del(int left, int right)
    {
        int k = 1;
        while (edge_min[left][k] != right)k ++;
        while (k < edge_min[left][0]) edge_min[left][k] = edge_min[left][k + 1], k ++;
        k = 1;
        while (edge_min[right][k] != left) k ++;
        while (k < edge_min[right][0]) edge_min[right][k] = edge_min[right][k + 1], k ++;
        edge_min[left][0]--;
        edge_min[right][0] --;
    }
    
    int find(int x)
    {
        if (x != parent[x]) x = find(parent[x]);
        return parent[x];
    }
    
    int point_find;
    void find_max(int parent, int current, int left , int right, int val)
    {
        if (point_find == current)
        {
            fleft = left;
            fright = right;
            fval  = val;
            return;
        }
        for (int i = 1; i <= edge_min[current][0]; i ++)
        {
            if (parent != edge_min[current][i])
            {
                if (e[current][edge_min[current][i]] > val)
                {
                    find_max(current, edge_min[current][i], current, edge_min[current][i], e[current][edge_min[current][i]]);
                }
                else
                {
                    find_max(current, edge_min[current][i], left, right, val);
                }
            }
        }
        return;
    }
    
    int cmp(const node &a , const node &b)
    {
        if (a.val <= b.val)
        {
            return true;
        }
        return false;
    }
    
    void init()
    {
        int i, x, y, val;
        for (i = 1; i <= n; i ++)
        {
            parent[i]  = i;
        }
        for (i = 0; i < m; i ++)
        {
            scanf("%d%d%d", &edge[i].left, &edge[i].right, &edge[i].val);
            e[edge[i].left][edge[i].right] = e[edge[i].right][edge[i].left] = edge[i].val;
        }
        map_count = 0;
        sort(edge, edge + m, cmp);
        memset(edge_min, 0, sizeof(edge_min));
    }
    
    void krus()
    {
        int i = 0, cou = 0;
        sum = 0;
        int left, right, left_parent, right_parent, val;
    
        for (i = 0; i < m; i ++)
        {
            left = edge[i].left;
            right = edge[i].right;
            left_parent = find(left);
            right_parent = find(right);
    
            if (left_parent != right_parent)
            {
                parent[left_parent] = parent[right_parent];
                add(left, right);
                sum += edge[i].val;
                cou++;
            }
            else
            {
                find_max(left, right, 0, 0, 0);
                if (fval > edge[i].val)
                {
                    sum = sum + edge[i].val - fval;
                    del(fleft, fright);
                    map_count ++;
                    map[map_count].left = fleft;
                    map[map_count].right = fright;
                    map[map_count].val = fval;
                    add(edge[i].left, edge[i].right);
                }
                else
                {
                    map_count ++;
                    map[map_count] = edge[i];
                }
            }
            if (cou == n - 1)
            {
                break;
            }
        }
        i ++;
        while ( i < m)
        {
            map_count ++;
            map[map_count] = edge[i ++];
        }
        
        return;
    }
    
    int max_left[maxn][maxn], max_right[maxn][maxn];
    int max_val[maxn][maxn];
    
    void dfs(int parent, int current, int left, int right, int val)
    {
        int x;
        for (int i = 1; i <= edge_min[current][0]; i ++)
        {
            x = edge_min[current][i];
            if (x != parent)
            {
                if (e[current][x] > val)
                {
                    max_left[point_find][x] = current;
                    max_right[point_find][x] = x;
                    max_val[point_find][x] = e[current][x];
                    dfs(current, x, current, x, e[current][x]);
                }
                else
                {
                    max_left[point_find][x] =left;
                    max_right[point_find][x] = right;
                    max_val[point_find][x] = val;
                    dfs(current, x, left, right, val);
                }
            }
        }
    }
    
    bool judge()
    {
        for (int i = 1; i <= n ; i ++)
        {
            point_find = i;
            dfs(i, i, 0, 0, 0);
        }
    
        for (int i = 1; i <= map_count; i ++)
        {
            
            if (max_val[map[i].left][map[i].right] == map[i].val)
            {
                return false;
            }
        }
        return true;
    }
    
    int main()
    {
        int count_int;
        scanf("%d", &count_int);
        while (count_int --)
        {
            scanf("%d%d", &n, &m);
            init();
            krus();
            if (judge())
            {
                printf("%d\n", sum);
            }
            else
            {
                printf("Not Unique!\n");
            }
        }
        return 0;
    }
  • 相关阅读:
    CSplitterWnd 成员介绍及切分条的定制
    时空数据挖掘 Mining Complex SpatioTemporal Sequence Patterns
    动态布局切分窗口
    不管你现在多穷多蠢,只要抓住一个上升的载体你就能变成富人
    破解了小区宽带的限制
    VC6.0的若干实用小技巧
    恶搞程序发布(更新版本)
    WPF笔记
    做多维数据集需要注意的两个细节
    关于值类型和引用类型的备忘
  • 原文地址:https://www.cnblogs.com/cxiaoln/p/2440416.html
Copyright © 2011-2022 走看看