• HDU4263 Red Blue Spanning Tree 最小生成树活用


    /*
    *State: HDU4263    453MS    3784K    1452 B    C++
    *题目大意:
    *        有一个无向无权图,只含有红边跟蓝边,判断是否它有一棵
    *        最小生成树含有确定的k条蓝边。
    *解题思路:
    *        求一遍含蓝边最多的最小生成树,其中蓝边数为Max, 求一遍
    *        含蓝边最少的最小生成树,其中蓝边数为Min.如果k值处于[Min, Max]
    *        这个闭区间里面,那么该图含有题目要求的MST.
    *        为什么是这样呢:因为这两棵极端的MST合并在一起只有两种
    *        情况,1、就是只含有蓝边的环,这时候删掉一条蓝边,2、另一种情况
    *        是含有红边跟蓝边的环,这时候每删去一条红边,那么当前的MST的
    *        蓝边数就上升1,所以MST含有蓝边数是在[Min, Max]这个区间中。
    */
    View Code
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int MAXE = 1000005;
    const int MAXN = 1005;
    typedef struct _edge
    {
        int u, v, w;
    }E;
    
    E edge[MAXE];
    int fa[MAXN];
    
    int findSet(int x)
    {
        if(x != fa[x])
            fa[x] = findSet(fa[x]);
        return fa[x];
    }
    
    bool Union(int x, int y)
    {
        int a = findSet(x);
        int b = findSet(y);
        if(a == b)
            return false;
        fa[b] = a;
        return true;
    }
    
    void initSet()
    {
        for(int i = 0; i < MAXN; i++)
            fa[i] = i;
    }
    
    bool cmp1(const E &a, const E &b)
    {
        return a.w < b.w;
    }
    
    bool cmp2(const E &a, const E &b)
    {
        return a.w > b.w;
    }
    
    int main(void)
    {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif
        int n, m, k;
        while(scanf("%d %d %d", &n, &m, &k), n || m || k)
        {
            
            int u, v, w;
            char op[5];
            for(int i = 0; i < m; i++)
            {
                scanf("%s %d %d", op, &u, &v);
                if(op[0] == 'B')
                {
                    edge[i].u = u, edge[i].v = v;
                    edge[i].w = 1;
                }
                else
                {
                    edge[i].u = u, edge[i].v = v;
                    edge[i].w = 0;
                }
            }
            initSet();
            int Min = 0, Max = 0;
            sort(edge, edge + m, cmp1);
            for(int i = 0; i < m; i++)
            {
                if(Union(edge[i].u, edge[i].v) && edge[i].w)
                    Min++;
            }
            initSet();
            sort(edge, edge + m, cmp2);
            for(int i = 0; i < m; i++)
            {
                if(Union(edge[i].u, edge[i].v) && edge[i].w)
                    Max++;
            }
            if(k >= Min && k <= Max)
                printf("1\n");
            else
                printf("0\n");
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/cchun/p/2656957.html
Copyright © 2020-2023  润新知