NOIP模拟 正直糖豆(最大流)

【描述】

L为了准备他的正直模拟赛又发明了了一种“教授糖豆”,该糖豆会给服用的人增加一定的正直值。由于机房中N个人的接受能力是有现的,正直值过大会影响和谐,正直值过小又影响团结,所以学员I分到的糖豆的正直值P必须在范围MAXi,MINi之间,既MINi<=P<=MAXi。给出M种糖豆及每种的个数,以及机房中每个人可接受的的正直范围,求最多能有几个人同时得到合适的糖豆。每个人最多得到一个糖豆。

【输入】

第一行:两个整数N和M

第二到N+1行:每行两个整数MINi,MAXi。第i行表示第i-1个人可接受的正直范围。

第N+2行到第N+M+1行:每行两个整数,分别表示糖豆的正直值和数量。

输出

一行一个整数表示最多有多少个人能同时得到合适的糖豆。

【样例输入】

3 2
3 10
2 5
1 5
6 2
4 1

【样例输出 】

2

【提示】

100%:1<=n<=2500,1<=m<=2500,1<=MINi,MAXi<=1000,1<=Pi<=1000

这个题的规模非常的迷啊,开了2e6的数组才过。。。总体来说还是很简单的,网络流(或二分图匹配,这里写网络流版本)模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=2e6+10;
const ll INF=0x3f3f3f3f;

ll n,m,cnt,stul[MAXN],stur[MAXN],sug[MAXN];
ll head[MAXN],to[MAXN],w[MAXN],nxt[MAXN];
ll cur[MAXN];
ll depth[MAXN],s,t;
ll Read()
{
	ll i=0,f=1;
	char c;
	for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
	if(c=='-')
	  f=-1,c=getchar();
	for(;c>='0'&&c<='9';c=getchar())
	  i=(i<<3)+(i<<1)+c-'0';
	return i*f;
}

void add(ll x,ll y,ll z)
{
	nxt[cnt]=head[x];
	head[x]=cnt;
	to[cnt]=y;
	w[cnt]=z;
	cnt++;
}

bool bfs()
{
	queue<ll> q;
	while(!q.empty())
	{
		q.pop();
	}
	for(ll i=0;i<=n+m+1;++i)
	  depth[i]=0;
	depth[s]=1;
	q.push(s);
	do
	{
		ll u=q.front();
		q.pop();
		for(ll i=head[u];i!=-1;i=nxt[i])
		{
			ll v=to[i];
			if(w[i]>0&&depth[v]==0)
			{
				depth[v]=depth[u]+1;
				q.push(v);
			}
		}
	}while(!q.empty());
	if(depth[t]==0)
	  return 0;
	return 1;
}

ll dfs(ll u,ll dis)
{
	if(u==t)
	  return dis;
	for(ll &i=cur[u];i!=-1;i=nxt[i])
	{
		ll v=to[i];
		if(depth[v]==depth[u]+1&&w[i]!=0)
		{
			ll di=dfs(v,min(w[i],dis));
			if(di>0)
			{
				w[i]-=di;
				w[i^1]+=di;
				return di;
			}
		}
	}
	return 0;
}

ll dinic()
{
	ll ans=0;
	while(bfs())
	{
		for(ll i=0;i<=n+m+1;++i)
		  cur[i]=head[i];
		while(ll d=dfs(s,INF))
		  ans+=d;
	}
	return ans;
}

int main()
{
	for(ll i=0;i<=n+m+1;++i)
	  head[i]=nxt[i]=-1; 
	n=Read(),m=Read();
	t=n+m+1; 
	for(ll i=1;i<=n;++i)
	  stul[i]=Read(),stur[i]=Read(),add(0,i,1),add(i,0,0);
	for(ll i=1;i<=m;++i)
	{
		ll num;
		sug[i]=Read(),num=Read();
		add(i+n,t,num),add(t,i+n,0);
		for(ll j=1;j<=n;++j)
		  if(sug[i]>=stul[j]&&sug[i]<=stur[j])
		    add(j,i+n,1),add(i+n,j,0);
	}
	printf("%lld",dinic());
	return 0;
}

 

posted @ 2018-08-15 20:38  Ishtar~  阅读(166)  评论(0编辑  收藏  举报