zoukankan      html  css  js  c++  java
  • Luogu P3033 [USACO11NOV]牛的障碍Cow Steeplechase(二分图匹配)

    P3033 [USACO11NOV]牛的障碍Cow Steeplechase

    题意

    题目描述

       --+-------
    -----+-----
      ---+---     |
         |     |  |
       --+-----+--+-   |
         |     |  |  | |
         |   --+--+--+-+-
               |  |  | |
                  |
    
       ----------
    -----------
      -------     |
               |  |
               |  |    |
               |  |  | |
               |  |  | |
               |  |  | |
                  |
    

    给出(N)平行于坐标轴的线段,要你选出尽量多的线段使得这些线段两两没有交点(顶点也算),横的与横的,竖的与竖的线段之间保证没有交点,输出最多能选出多少条线段。

    输入输出样例

    输入样例#1:

    3
    4 5 10 5
    6 2 6 12
    8 3 8 5
    

    输出样例#1:

    2
    

    思路

    其实这题就一句话:二分图最大独立集大小=总点数-最大匹配数。

    二分图匹配就好了。

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=255;
    int n,ans,match[MAXN],xx[MAXN],yy[MAXN],xxx[MAXN],yyy[MAXN];
    int cnt,top[MAXN],to[MAXN*MAXN],nex[MAXN*MAXN];
    bool vis[MAXN];
    int read()
    {
        int re=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
        return re;
    }
    void add_edge(int x,int y){to[++cnt]=y,nex[cnt]=top[x],top[x]=cnt;}
    bool dfs(int now)
    {
        for(int i=top[now];i;i=nex[i])
            if(!vis[to[i]])
            {
                vis[to[i]]=true;
                if(!match[to[i]]||dfs(match[to[i]]))
                {
                    match[to[i]]=now;
                    return true;
                }
            }
        return false;
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            xx[i]=read(),yy[i]=read(),xxx[i]=read(),yyy[i]=read();
            if(xx[i]>xxx[i]) swap(xx[i],xxx[i]);
            if(yy[i]>yyy[i]) swap(yy[i],yyy[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(xx[i]!=xxx[i]) continue;
            for(int j=1;j<=n;j++)
            {
                if(yy[j]!=yyy[j]) continue;
                if(yy[i]<=yy[j]&&yy[j]<=yyy[i]&&xx[j]<=xx[i]&&xx[i]<=xxx[j]) add_edge(i,j);
            }
        }
        for(int i=1;i<=n;i++)
            if(xx[i]==xxx[i])
            {
                memset(vis,false,sizeof vis);
                if(dfs(i)) ans++;
            }
        printf("%d",n-ans);
        return 0;
    }
    
  • 相关阅读:
    C# linq lambda 分组获取最新的数据
    C# SQLite datetime 时间比较查询
    .net core webApi 上传附件
    ①、Vue学习
    阿里云单片上传、断点续传,上传到指定文件夹下面
    php设计模式之策略模式
    composer安装laravel
    php全局配置
    windows系统安装composer
    php设计模式之工厂模式
  • 原文地址:https://www.cnblogs.com/coder-Uranus/p/9905094.html
Copyright © 2011-2022 走看看