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 }

 

你可能感兴趣的:(sign)