POJ 3189
题意:
给你B个谷仓和n头牛,每个谷仓最多容纳m头牛。此时每头牛对每一个谷仓都有一个喜悦值,你需要把每一头牛都安排某个谷仓内,并且找出来那个每一头牛对它所住的谷仓打的分值,我们对这所有的分值取一个区间,使这个区间包含这每一个值。并且尽量使这个区间小一点。
题解:
对着区间的两个端点[l,r],先让l==r==1,之后如果在区间[l,r]中分配不成(就使用二分图多重匹配算法来判断)牛群的话就让r++,如果分配成功的话,那么就得让l++
代码:
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<iostream> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 const int maxn=1010; 9 const int INF=0x3f3f3f3f; 10 int n,m; 11 int g[maxn][maxn],mp[maxn][maxn],visit[maxn],match[maxn],link[maxn][maxn]; 12 int cap[maxn],l,r; 13 int dfs_solve(int u) 14 { 15 int v; 16 for(int v=1;v<=m;v++) 17 { 18 if(mp[u][v]<=r && mp[u][v]>=l && !visit[v]) 19 { 20 visit[v]=1; 21 if(match[v]<cap[v]) 22 { 23 link[v][++match[v]]=u; 24 return 1; 25 } 26 for(int i=1;i<=cap[v];i++) 27 { 28 if(dfs_solve(link[v][i])) 29 { 30 link[v][i]=u; 31 return 1; 32 } 33 } 34 } 35 } 36 return 0; 37 } 38 int hungran() 39 { 40 int ans=0; 41 memset(match,0,sizeof(match)); 42 memset(link,-1,sizeof(link)); 43 for(int i=1;i<=n;++i) 44 { 45 memset(visit,0,sizeof(visit)); 46 ans+=dfs_solve(i); 47 } 48 return ans; 49 } 50 int main() 51 { 52 int k,x; 53 while(~scanf("%d%d",&n,&m)) 54 { 55 memset(mp,0,sizeof(mp)); 56 for(int i=1;i<=n;++i) 57 { 58 for(int j=1;j<=m;++j) 59 { 60 int a; 61 scanf("%d",&a); 62 mp[i][a]=j; 63 } 64 } 65 for(int i=1;i<=m;++i) 66 scanf("%d",&cap[i]); 67 l=r=1; 68 int ans=INF; 69 while(l<=r && r<=m) 70 { 71 if(hungran()==n) 72 { 73 ans=min(ans,r-l+1); 74 l++; 75 } 76 else r++; 77 } 78 printf("%d\n",ans); 79 } 80 return 0; 81 }