POJ 3614 Sunscreen 最大流、多重匹配、貪心
阿新 • • 發佈:2018-12-29
#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()); } }
二分圖多重匹配: