zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    TCP/IP详解V2(六)之TCP协议
    TCP/IP详解V2(四)之TCP协议
    TCP/IP详解V2(三)之TCP协议
    epoll源码剖析
    UDT源码剖析(二)之启动与结束
    TCP/IP详解V2(二)之UDP协议
    TCP/IP详解V2(一)之协议控制块
    UDT源码剖析(一)之总览
    SPI通信协议(SPI总线)学习
    第12章Cortex-M4-SPI-Bus
  • 原文地址:https://www.cnblogs.com/cchun/p/2656957.html
Copyright © 2011-2022 走看看