zoukankan      html  css  js  c++  java
  • 376. 机器任务(最小点覆盖)

    376. 机器任务

    最小点覆盖==最大匹配.

    最小点的覆盖由于所有的边,所以对于每一个边来说,两边的点至少要选一个..

    这就是最小点覆盖的2性质...

    针对于这道题我们思考对于每个任务,要求a[i],b[i]至少要有一个模式,所以我们就将a的模式放一边,b的模式放一半,对于每一个任务连边

    最后做最大匹配.

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=110,M=1010;
    int n,m,match[N],vis[N],link[N],tot,id,k;
    struct edge{int y,next;}a[M];
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline void add(int x,int y)
    {
        a[++tot].y=y;
        a[tot].next=link[x];
        link[x]=tot;
    }
    inline bool dfs(int x)
    {
        for(int i=link[x];i;i=a[i].next)
        {
            int y=a[i].y;
            if(vis[y]!=id)
            {
                vis[y]=id;
                if(!match[y]||dfs(match[y])) {match[y]=x;return true;}
            }
        }
        return false;
    }
    int main()
    {
        //freopen("1.in","r",stdin);
        while(n=read())
        {
            memset(a,0,sizeof(a));tot=0;
            memset(link,0,sizeof(link));
            memset(match,0,sizeof(match));
            m=read();k=read();
            for(int i=1;i<=k;++i)
            {
                int id=read(),x=read(),y=read();
                if(x==0||y==0) continue;
                add(x,y);
            }
            int ans=0;
            for(int i=1;i<=n;++i)
            {
                ++id;
                if(dfs(i)) ans++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Arrays类总结
    多维数组
    数组
    写一个计算器,要求实现加减乘除功能,能够循环接收收据,通过用户交互实现
    递归
    方法
    函数
    流程控制
    mysql笔记(连接与子查询部分)
    ubuntu下mysql的常用命令
  • 原文地址:https://www.cnblogs.com/gcfer/p/12449324.html
Copyright © 2011-2022 走看看