题目链接: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 }