有n头牛,m个牛棚,每头牛对牛棚的满意程度有一个排序,每个牛棚有牛数限制。
问如何分配各个牛,使得所有牛的满意程度的差值最小。
这题首先可以想到二分答案,对于每一种差值来求是否可行。
不想再搞网络流,学习了下二分图匈牙利解法。。
匹配时,对于每一种选择(牛棚),若满足范围,且有多余的容量,则匹配;
否则,对于该牛棚已经匹配过的牛进行增广。
#include <iostream> #include <cstdlib> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #pragma comment(linker, "/STACK:16777216") #define eps 1e-6 #define ll __int64 const int maxn=1005; using namespace std; int link[25][maxn],rk[maxn][25],cap[maxn],num[maxn]; bool vis[maxn]; int n,m,r,l; int path(int u) { int v; for(v=0;v<m;v++) { if(rk[u][v]>=r&&rk[u][v]<=l&&!vis[v]) { vis[v]=1; if(num[v]<cap[v]) { link[v][++num[v]]=u;// v牛棚的第num[v]头牛 return 1; } for(int i=1;i<=cap[v];i++) { if(path(link[v][i])) { link[v][i]=u; return 1; } } } } return 0; } int hungry() { memset(num,0,sizeof num); memset(link,-1,sizeof link); for(int i=0;i<n;i++) { memset(vis,0,sizeof vis); if(!path(i)) return 0; } return 1; } int main() { int mid,ans,i,j; while(~scanf("%d%d",&n,&m)) { for(i=0;i<n;i++) for(j=0;j<m;j++) { scanf("%d",&ans); rk[i][--ans]=j;//存ans这个牛棚对于i这头牛的排序是多少 } for(i=0;i<m;i++) scanf("%d",&cap[i]); r=l=0; ans=inf; while(r<=l&&l<m) { mid=l-r+1; if(hungry()) { r++; if(mid<ans) ans=mid; } else l++; } printf("%d\n",ans); } return 0; }
时间: 2024-10-07 05:27:09