• hdu1054(二分图匹配)


    题意很简单,在一颗树上找最小点覆盖。

    将树染成黑白两色,构成一张二分图,然后最大匹配==最小点覆盖即可,所以一次匈牙利就可以求出来了

    hdu1054

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    #include <string>
    #include <queue>
    #include <vector>
    #include <stdlib.h>
    using namespace std;
    #define N 1505
    
    int n;
    struct node
    {
        int to,next;
    }edge[N*2];
    
    vector<int>g[N];
    
    int pre[N],cnt;
    int cao[N],a[N],b[N];
    int cnta,cntb;
    int mark[N],frt[N];
    
    void add_edge(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=pre[u];
        pre[u]=cnt++;
    }
    
    void Dfs(int s,int fr,int flag)
    {
        if(flag==0)
        {
            cao[s]=cnta;
            a[cnta]=s;
            cnta++;
        }else
        {
            cao[s]=cntb;
            b[cntb]=s;
            cntb++;
        }
        for(int p=pre[s];p!=-1;p=edge[p].next)
        {
            int v=edge[p].to;
            if(v==fr) continue;
            Dfs(v,s,flag^1);
        }
    }
    
    int dfs(int s)
    {
        for(int i=0;i<g[s].size();i++)
        {
            int v=g[s][i];
            if(mark[v]==1) continue;
            mark[v]=1;
            if(frt[v]==-1||dfs(frt[v]))
            {
                frt[v]=s;
                return 1;
            }
        }
        return 0;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            cnt=0;
            memset(pre,-1,sizeof(pre));
            for(int i=0;i<n;i++)
            {
                int x;
                scanf("%d",&x);
                int num;
                scanf(":(%d)",&num);
                for(int j=0;j<num;j++)
                {
                    int y;
                    scanf("%d",&y);
                    add_edge(x,y);
                    add_edge(y,x);
                }
            }
            //然后就是染色了
            cnta=0; cntb=0;
            Dfs(0,-1,0);
            //然后再建一张图
            for(int i=0;i<cnta;i++)
            {
                g[i].clear();
                for(int p=pre[a[i]];p!=-1;p=edge[p].next)
                {
                    int v=edge[p].to;
                    g[i].push_back(cao[v]);
                }
            }
            int ans=0;
            memset(frt,-1,sizeof(frt));
            for(int i=0;i<cnta;i++)
            {
                memset(mark,0,sizeof(mark));
                ans+=dfs(i);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [Flex] Flex 控件&类 的自定义事件添加
    [java]原始类型和其包装类
    [java]解析网络上的xml文件
    [android]用adb操作android模拟器
    [java]优先队列
    [Q&A]为什么在ospf邻居之间确定主从关系?
    [js]jQuery插件开发总结
    [Q&A] 为什么把js脚本放到html页面的底部?
    理解一个简单的网页请求过程
    [js]如何更快的得到图片的高度和宽度
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/4077638.html
Copyright © 2020-2023  润新知