题意:n个牛找B个槽子,对于每个槽子有不同的满意度,槽子有容量限制,让所有牛找到自己的槽子,满意差距尽可能少
思路:二分答案+二分图匹配
注意:二分答案要注意上界下界,本题我的做法下界应该取0,取1会WA
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
typedef double db;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define me0(ar) memset(ar,0,sizeof ar)
#define me1(ar) memser(ar,-1,sizeof ar)
const int N=1e3+5;
int n,b;
int c[N],g[N][N],lin[N][N];
bool vis[N];
bool dfs(int p,int x,int y){
rep(i,x,y){
int v=g[p][i];
if(vis[v]) continue;
vis[v]=1;
if(lin[v][0]<c[v]){
lin[v][++lin[v][0]]=p;
return 1;
}
rep(j,1,lin[v][0])
if(dfs(lin[v][j],x,y)){
lin[v][j]=p;
return 1;
}
}
return 0;
}
bool pd(int x,int y){
me0(lin);
rep(i,1,n){
me0(vis);
if(!dfs(i,x,y)) return 0;
}
return 1;
}
bool op(int d){
rep(i,1,b-d)
if(pd(i,i+d)) return 1;
return 0;
}
int main(){
while(cin>>n>>b){
me0(g);
me0(c);
rep(i,1,n)
rep(j,1,b) cin>>g[i][j];
rep(i,1,b) cin>>c[i];
int l=0,r=b,ans;
while(l<r){
int m=(l+r)>>1;
if(op(m)) r=m;
else l=m+1;
}
cout<<l+1<<endl;
}
return 0;
}