牛客 羊吃草(二分图)

题目链接: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

题解

  因为每个位置只能被其中一只羊占据,所以可以将羊和位置分别看成二分图的两部分,将位置与羊匹配,如何建图?每只羊能占据的区间是给出,我们只需要将该区间的每一点连向羊,查询的时候从 l 到 r 跑一遍最大匹配即可,所以总复杂度为O(n^3)。

#include<bits/stdc++.h>
using namespace std;
#define maxn 405
#define ll long long
#define inf 1000000009
#define IOS ios::sync_with_stdio(false)

struct edge
{
    int next,to;
}love[maxn*maxn];
int head[maxn],num;
void add(int from,int to)
{
    love[++num].next=head[from];
    love[num].to=to;
    head[from]=num;
}

int n;//n为男孩最大值
int used[maxn], girl[maxn];//这两个数组的大小应为girl的最大值
vector<int>V;//避免对used每次memset的优化
bool find(int x)
{
    for (register int j = head[x]; j; j = love[j].next)  //扫描每个妹子
    {
        int v = love[j].to;
        if (used[v] == false)
            //如果有暧昧并且还没有标记过(这里标记的意思是这次查找曾试图改变过该妹子的归属问题,
            //但是没有成功,所以就不用瞎费工夫了)
        {
            used[v] = 1;
            V.push_back(v);
            if (girl[v] == 0 || find(girl[v]))
            {
                //名花无主或者能腾出个位置来,这里使用递归
                girl[v] = x;
                return true;
            }
        }
    }
    return false;
}

int Hungary(int x,int y)
{
    int all = 0;
    memset(used,0,sizeof(used));
    memset(girl,0,sizeof(girl));
    for (int i = x; i <= y; i++)
    {
        if (find(i))
            all += 1;
        for (int i = 0; i<V.size(); i++)
            used[V[i]] = false;
        V.clear();
    }
    return all;
}

int L[maxn],R[maxn];
int main()
{
    IOS;
    int q;
    cin>>n>>q;
    for(int i=1;i<=n;i++)
        cin>>L[i];
    for(int i=1;i<=n;i++)
        cin>>R[i];

    for(int i=1;i<=n;i++)
        for(int j=L[i];j<=R[i];j++)
            add(j,i);

    while(q--)
    {
        int x,y;
        cin>>x>>y;
        cout<<Hungary(x,y)<<"\n";
    }
    return 0;
}
发布了41 篇原创文章 · 获赞 2 · 访问量 1244

猜你喜欢

转载自blog.csdn.net/qq_41418281/article/details/100587752