解题报告
http://blog.csdn.net/juncoder/article/details/38340447
题目传送门
题意:
B个猪圈,N头猪。每头猪对每一个猪圈有一个惬意值。要求安排这些猪使得最大惬意和最小惬意的猪差值最小
思路:
二分图的多重匹配问题;
猪圈和源点连边,容量为猪圈容量。猪与汇点连边,容量1;
猪圈和猪之间连线取决所取的惬意值范围;
二分查找惬意值最小差值的范围。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #define inf 99999999 using namespace std; int n,m,b,mmap[1030][22],edge[1030][1030],l[1030],c[22]; int bfs() { memset(l,-1,sizeof(l)); l[0]=0; int i; queue<int >Q; Q.push(0); while(!Q.empty()) { int u=Q.front(); Q.pop(); for(i=0; i<=m; i++) { if(edge[u][i]&&l[i]==-1) { l[i]=l[u]+1; Q.push(i); } } } if(l[m]>1)return 1; return 0; } int dfs(int x,int f) { if(x==m)return f; int i,a; for(i=0; i<=m; i++) { if(l[i]==l[x]+1&&edge[x][i]&&(a=dfs(i,min(f,edge[x][i])))) { edge[x][i]-=a; edge[i][x]+=a; return a; } } l[x]=-1; return 0; } int dinic() { int ans=0,a; while(bfs()) while(a=dfs(0,inf)) ans+=a; return ans; } int cow(int mid) { int i,j,k; for(i=1; i<=b-mid+1; i++) { memset(edge,0,sizeof(edge)); for(j=1; j<=b; j++) { edge[0][j]=c[j]; } for(j=1; j<=n; j++) { for(k=i; k<=i+mid-1; k++) { edge[mmap[j][k]][j+b]=1; } edge[j+b][m]=1; } if(dinic()==n) return 1; } return 0; } int main() { int i,j; while(~scanf("%d%d",&n,&b)) { memset(mmap,0,sizeof(mmap)); memset(c,0,sizeof(c)); m=n+b+1; for(i=1; i<=n; i++) { for(j=1; j<=b; j++) { scanf("%d",&mmap[i][j]); } } for(i=1; i<=b; i++) { scanf("%d",&c[i]); } int l=1,r=b,t=-1; while(l<=r) { int mid=(l+r)/2; if(cow(mid)) { t=mid; r=mid-1; } else { l=mid+1; } } printf("%d\n",t); } return 0; }
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5369 | Accepted: 1845 |
Description
Input
Output
Sample Input
6 4 1 2 3 4 2 3 1 4 4 2 3 1 3 1 2 4 1 3 4 2 1 4 2 3 2 1 3 2
Sample Output
2
Hint