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\n", solve() );
    }
    return 0;
}

 

posted @ 2015-08-10 17:21  向前走丶不回首  阅读(114)  评论(0编辑  收藏  举报