zoukankan      html  css  js  c++  java
  • 牛客练习赛51 D题

    链接:https://ac.nowcoder.com/acm/contest/1083/D
    来源:牛客网
     
    有一个草原可以用一个1~400的数轴表示。有n头羊和q个查询。每头羊的编号分别是1,2,3…n。第i头羊只喜爱数轴上[ai,bi]这样的一个闭区间,每一时刻每头羊只可能在自己喜爱的区间的某个点上吃草。现在给出q个查询,每个查询两个整数l,r。你需要计算出在同一时刻,最多能有多少头羊同时在这个区间内吃草。数轴上每一个整点同一时刻只能容纳一只羊,羊只会在整点吃草。

    第一行三个数n q。

    第二行n个数a1 a2…an。

    第三行n个数b1 b2…bn。

    接下来q行每行两个数l,r。表示询问的区间。

    输入:

    5 3
    1 1 1 2 4
    1 1 1 3 5
    1 5
    2 5
    1 3

    输出:

    3
    2
    2

    思路:

    设坐标轴的整点1...400属于集合A,羊1...n属于集合B,对于编号为i的羊喜欢的区间a[i],b[i],我们在集合B的i点和集合A中的a[i]...b[i]的点之间连一条边,可以发现这样的图是一张二分图。于是对于每次查询l,r,我们枚举集合A中l...r之间的所有点,求出其最大匹配集合。可以用匈牙利算法或足够优秀的最大流。【比较懒,直接搬的题解QAQ】

    以下是我匈牙利算法的代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int maxn=510;
    int a[maxn];
    int b[maxn];
    int match[maxn];
    int book[maxn];
    int G[maxn][maxn];
    int l,r;
    int dfs(int u){    // 模板
        for(int i=l;i<=r;i++){
            if(book[i]==0&&G[u][i]==1){
                book[i]=1;
                if(match[i]==0||dfs(match[i])){
                    match[i]=u;
                //    match[u]=i;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main(){
        int n,Q;
        cin>>n>>Q;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            scanf("%d",&b[i]);
        while(Q--){
            memset(G,0,sizeof(G));
            scanf("%d%d",&l,&r);
            for(int i=1;i<=n;i++){
                if(a[i]>=l&&b[i]<=r){
                    for(int j=a[i];j<=b[i];j++){
                        G[i][j]=1;
                    }
                }else if(a[i]<=r&&b[i]>=r){
                    for(int j=l;j<=r;j++){
                        G[i][j]=1;
                    }
                }else if(a[i]<=l&&b[i]<=r){
                    for(int j=l;j<=b[i];j++){
                        G[i][j]=1;
                    }
                }else if(a[i]>=l&&b[i]>=r){
                    for(int j=a[i];j<=r;j++){
                        G[i][j]=1;
                    }
                }
            }
            int ans=0;
            memset(match,0,sizeof(match));
            for(int i=1;i<=n;i++){
                memset(book,0,sizeof(book));
                if(dfs(i))
                    ans++;
            }
            printf("%d
    ",ans);
            
        }
        return 0;
    }
        
    D 羊吃草
  • 相关阅读:
    P3970 [TJOI2014]上升子序列
    受欢迎的牛(Tarjan缩点模板)
    Y15BeTa的乱搞方法(占坑待填)
    Luogu P4145 上帝造题的七分钟2 / 花神游历各国
    Luogu P1525 【关押罪犯】
    Luogu P1077 摆花 NOIP2012pjT3
    Nowcoder deco的abs
    CSP-S前的芝士清单
    普天同庆
    线段树区改区查标记永久化板子
  • 原文地址:https://www.cnblogs.com/pengge666/p/11479315.html
Copyright © 2011-2022 走看看