Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1966 | Accepted: 688 |
Description
To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they're at the beach. Cowi has a minimum and maximumSPF rating (1 ≤ minSPFi ≤ 1,000;minSPFi ≤maxSPFi ≤ 1,000) that will work. If theSPF rating is too low, the cow suffers sunburn; if theSPF rating is too high, the cow doesn't tan at all........
The cows have a picnic basket with L (1 ≤ L ≤ 2500) bottles of sunscreen lotion, each bottlei with anSPF rating SPFi (1 ≤ SPFi ≤ 1,000). Lotion bottlei can covercoveri cows with lotion. A cow may lotion from only one bottle.
What is the maximum number of cows that can protect themselves while tanning given the available lotions?
Input
* Line 1: Two space-separated integers: C and L
* Lines 2..C+1: Line i describes cow i's lotion requires with two integers:minSPFi andmaxSPFi
* Lines C+2..C+L+1: Line i+C+1 describes a sunscreen lotion bottlei with space-separated integers:SPFi and coveri
Output
A single line with an integer that is the maximum number of cows that can be protected while tanning
Sample Input
3 2 3 10 2 5 1 5 6 2 4 1
Sample Output
2
Source
贪心即可。
先将翻晒霜按spf值排序,从小到大处理。
对于当前处理的防晒霜,找到能使用它且spf上界最小的牛,将防晒霜供其使用。
因为上界越大,选择越多,在之后可能也可以找到匹配的防晒霜,
而由于从小到大处理,下界已经没有意义(不可能找到比当前spf更小的匹配),这是贪心的原则。
复杂度:O(l*logl+n*l)
转载自http://blog.163.com/benz_/blog/static/18684203020115612011262/
#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());
}
}
二分图多重匹配:
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int n,m,f[2505],size[2505];
vector<int> adj[2505],mat[2505];
pair<int,int> a[2505];
int dfs(int x)
{
int i,j,k,u,v;
for(i=0;i<adj[x].size();i++)
{
u=adj[x][i];
k=size[u];
if(!f[u])
{
f[u]=1;
if(mat[u].size()<k)
{
mat[u].push_back(x);
return 1;
}
for(j=0;j<mat[u].size();j++)
{
v=mat[u][j];
if(dfs(v))
{
mat[u][j]=x;
return 1;
}
}
}
}
return 0;
}
int ok()
{
int i,ans=0;
for(i=1;i<=m;i++)
mat[i].clear();
for(i=1;i<=n;i++)
{
memset(f,0,sizeof(f));
if(dfs(i))
ans++;
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i,j,u,v;
for(i=1;i<=n;i++)
{
scanf("%d%d",&u,&v);
a[i]=make_pair(u,v);
adj[i].clear();
}
sort(a+1,a+n+1);
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
size[i]=v;
for(j=1;j<=n;j++)
if(a[j].first<=u&&u<=a[j].second)
adj[j].push_back(i);
else if(a[j].first>u)
break;
}
printf("%d\n",ok());
}
}