1. 程式人生 > >POJ 3614 Sunscreen 最大流、多重匹配、貪心

POJ 3614 Sunscreen 最大流、多重匹配、貪心

#include<cstdio>
#include<cstring>
#define N 5005
#define M 2000005
#define inf 999999999
#include<algorithm>
using namespace std;

int n,m,s,t,num,adj[N],dis[N],q[N];
pair<int,int> a[2505];
struct edge
{
	int v,w,pre;
}e[M];
void insert(int u,int v,int w)
{
	e[num]=(edge){v,w,adj[u]};
	adj[u]=num++;
	e[num]=(edge){u,0,adj[v]};//有向圖
	adj[v]=num++;
}
int bfs()
{
	int i,x,v,head=0,tail=0;
	memset(dis,0,sizeof(dis));
	dis[s]=1;
	q[++tail]=s;
	while(head!=tail)
	{
		x=q[head=(head+1)%N];
		for(i=adj[x];~i;i=e[i].pre)
			if(e[i].w&&!dis[v=e[i].v])
			{
				dis[v]=dis[x]+1;
				if(v==t)
					return 1;
				q[tail=(tail+1)%N]=v;
			}
	}
	return 0;
}
int dfs(int x,int limit)
{
	if(x==t)
		return limit;
	int i,v,tmp,cost=0;
	for(i=adj[x];~i&&cost<limit;i=e[i].pre)
		if(e[i].w&&dis[x]==dis[v=e[i].v]-1)
		{
			tmp=dfs(v,min(limit-cost,e[i].w));
			if(tmp)
			{
				e[i].w-=tmp;
				e[i^1].w+=tmp;
				cost+=tmp;
			}
			else
				dis[v]=-1;
		}
	return cost;
}
int Dinic()
{
	int ans=0;
	while(bfs())
		ans+=dfs(s,inf);
	return ans;
}
int main()
{
	while(~scanf("%d%d",&n,&m))
	{
		int i,j,u,v;
		memset(adj,-1,sizeof(adj));
		num=0;
		s=0;
		t=m+n+1;
		for(i=1;i<=n;i++)
		{
			scanf("%d%d",&u,&v);
			a[i]=make_pair(u,v);
			insert(s,i,1);
		}
		sort(a+1,a+n+1);
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&u,&v);
			for(j=1;j<=n;j++)
				if(a[j].first<=u&&u<=a[j].second)
					insert(j,n+i,1);
				else if(a[j].first>u)
					break;
			insert(n+i,t,v);
		}
		printf("%d\n",Dinic());
	}
}

二分圖多重匹配: