zoukankan      html  css  js  c++  java
  • HDU 1054 Strategic Game

    题目大意:

    给你一棵树,问最少多少个点可以把树的所有路径都给覆盖了。
    题目输入:
    首先是一个数字n, 代表有n个结点。
    然后下面是n个节点的信息
    首先是一个数字 a 然后(b)  b代表和a相连节点的数目。
    然后是 b 个数字,代表和a相连。
     
    题目思路:
    先对图进行黑白染色,然后构造二分图,然后进行匹配。因为是有(1600个点,感觉需要用HK算法, 然而并不用,我直接匈牙利过了...........)
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define INF 0x3fffffff
    #define maxn 1705
    int color[maxn];/// 1白色 2 黑色
    int n, P[maxn], k, Head[maxn];
    bool vis[maxn];
    struct EdgeNode
    {
        int e, next;
    } edge[maxn*10];
    
    void AddEdge(int s, int e)
    {
        edge[k].next = Head[s];
        edge[k].e = e;
        Head[s] = k ++;
    }
    
    void DFS(int u,int Color)
    {
        color[u] = Color;
    
        for(int i=Head[u]; i != -1; i=edge[i].next)
        {
            int v = edge[i].e;
            if(color[v] == 0)
                DFS(v, -Color);
        }
    }
    
    bool Find(int u)
    {
        for(int i=Head[u]; i!=-1; i=edge[i].next)
        {
            int v = edge[i].e;
            if(!vis[v] )
            {
                vis[v] = true;
                if(P[v] == -1 || Find(P[v]) )
                {
                    P[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    
    int solve()
    {
        int ans = 0;
        memset(P, -1, sizeof(P));
        memset(color, 0, sizeof(color));
        DFS(0, 1);///对图进行黑白染色
        for(int i=0; i<n; i++)
        {
            memset(vis, false, sizeof(vis));
            if(color[i] == 1 && Find(i))
                ans ++;
        }
        return ans;
    }
    
    int main()
    {
        while( scanf("%d", &n) != EOF)
        {
            int a, b, m;
            k = 0;
            memset(Head, -1, sizeof(Head));
    
            for(int i=0; i<n; i++)
            {
                scanf("%d:(%d)", &a, &m);
                while(m --)
                {
                    scanf("%d", &b);
                    AddEdge(a, b);
                    AddEdge(b, a);
                }
            }
            printf("%d
    ", solve() );
        }
        return 0;
    }
  • 相关阅读:
    RDMA技术详解(二):RDMA Send Receive操作
    RDMA技术详解(一):RDMA概述
    Fedora中制作UEFI/BIOS启动的U盘安装盘
    Fedora中制作BIOS启动的U盘安装盘
    chkdsk /f
    单片机原理及应用---实验计划
    LeetCode 645. Set Mismatch(错误的集合)
    LeetCode 401. Binary Watch(二进制手表)
    LeetCode 852. Peak Index in a Mountain Array(山脉数组的峰顶索引)
    LeetCode 518. Coin Change 2(零钱兑换 II)
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718595.html
Copyright © 2011-2022 走看看