POJ-3189 Steady Cow Assignment 二分+匹配

  题目链接:http://poj.org/problem?id=3189

  无语了,再次碰到Farmer John,又是二分+匹配的题目= =!注意题目要求求的是range最小,就是最大的rank-最小的rank!

  1 //STATUS:G++_AC_94MS_1500KB
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<math.h>
  6 #include<iostream>
  7 #include<string>
  8 #include<algorithm>
  9 #include<vector>
 10 #include<queue>
 11 #include<stack>
 12 #include<map>
 13 using namespace std;
 14 #define LL __int64
 15 #define pii pair<int,int>
 16 #define Max(a,b) ((a)>(b)?(a):(b))
 17 #define Min(a,b) ((a)<(b)?(a):(b))
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define lson l,mid,rt<<1
 20 #define rson mid+1,r,rt<<1|1
 21 const int MAX=2100,INF=0x3f3f3f3f;
 22 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
 23 
 24 struct Edge{
 25     int u,v,cap;
 26 }e[MAX*MAX*2];
 27 
 28 int first[MAX],next[MAX*MAX*2];
 29 int w[MAX][25],d[MAX],cur[MAX],p[MAX],num[MAX],hav[25];
 30 int n,m,s,t,mt;
 31 
 32 void adde(int a,int b,int val)
 33 {
 34     e[mt].u=a;e[mt].v=b;
 35     e[mt].cap=val;
 36     next[mt]=first[a];first[a]=mt++;
 37     e[mt].u=b;e[mt].v=a;
 38     e[mt].cap=0;
 39     next[mt]=first[b];first[b]=mt++;
 40 }
 41 
 42 int augment()
 43 {
 44     int x=t,a=INF;
 45     while(x!=s){
 46         a=Min(a,e[p[x]].cap);
 47         x=e[p[x]].u;
 48     }
 49     x=t;
 50     while(x!=s){
 51         e[p[x]].cap-=a;
 52         e[p[x]^1].cap+=a;
 53         x=e[p[x]].u;
 54     }
 55     return a;
 56 }
 57 
 58 int isap()
 59 {
 60     int i,flow=0,x,ok,min;
 61     mem(d,0);mem(num,0);
 62     num[0]=t+1;
 63     for(i=0;i<=t;i++)cur[i]=first[i];
 64     x=s;
 65     while(d[s]<=t){
 66         if(x==t){
 67             flow+=augment();
 68             x=s;
 69         }
 70         ok=0;
 71         for(i=cur[x];i!=-1;i=next[i]){
 72             if(e[i].cap && d[x]==d[e[i].v]+1){
 73                 ok=1;
 74                 p[e[i].v]=i;
 75                 cur[x]=i;
 76                 x=e[i].v;
 77                 break;
 78             }
 79         }
 80         if(!ok){
 81             min=t;
 82             for(i=first[x];i!=-1;i=next[i])
 83                 if(e[i].cap && d[e[i].v]<min)min=d[e[i].v];
 84             if(--num[d[x]]==0)break;
 85             num[d[x]=min+1]++;
 86             cur[x]=first[x];
 87             if(x!=s)x=e[p[x]].u;
 88         }
 89     }
 90     return flow;
 91 }
 92 
 93 int binary(int r)
 94 {
 95     int i,j,low=r,high=m+1,mid,ok=0;
 96     while(low<high){
 97         mid=(low+high)>>1;
 98         mt=0;
 99         mem(first,-1);
100         for(i=1;i<=n;i++){
101             adde(s,i,1);
102             for(j=r;j<=mid;j++)
103                 adde(i,n+w[i][j],1);
104         }
105         for(i=1;i<=m;i++)
106             adde(n+i,t,hav[i]);
107         int tt=isap();
108         if(tt<n)low=mid+1;
109         else {
110             if(tt==n)ok=1;
111             high=mid;
112         }
113     }
114     return ok?low-r+1:INF;
115 }
116 
117 int main()
118 {
119  //   freopen("in.txt","r",stdin);
120     int i,j,ans,tt;
121     while(~scanf("%d%d",&n,&m))
122     {
123         ans=INF;
124         s=0,t=n+m+1;
125         for(i=1;i<=n;i++)
126             for(j=1;j<=m;j++)
127                 scanf("%d",&w[i][j]);
128         for(i=1;i<=m;i++)
129             scanf("%d",&hav[i]);
130 
131         for(i=1;i<=m;i++){
132             tt=binary(i);
133             if(tt<ans)ans=tt;
134             if(ans==1)break;
135         }
136         printf("%d\n",ans);
137     }
138     return 0;
139 }

 

posted @ 2012-12-06 17:02  zhsl  阅读(274)  评论(0编辑  收藏  举报