Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4267 | Accepted: 1503 |
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
Source
//有n(<=1000)头牛, b(<=20)个牛棚, 每个牛棚有自己的容量, 每头牛按喜好程度为b个牛棚打上不同的分数, //现在分配牛去牛棚, 设第i头牛对分配的牛棚的喜好值为rank[i], //问在不挤爆牛棚的前提下, 怎样分配, 使得max{rank[i]}-min{rank[j]}最小 //用两个指针不后退的往前扫,不断求最大流即可 #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define M 4100 const int inf=1<<30; int gap[M],dis[M],pre[M],cur[M]; int NE,NV,sink,source; int head[M],n,m,rank[M][M],cap[M]; struct Node { int c,pos,next; } E[999999]; #define FF(i,NV) for(int i=0;i<NV;i++) int sap(int s,int t) { memset(pre,-1,sizeof(pre)); memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug =inf; gap[0] = NV; while(dis[s] < NV) { loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c >0&& dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug = inf; } goto loop; } } int mindis = NV; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } if( (--gap[dis[u]]) == 0)break; gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow; } void addEdge(int u,int v,int c ) { E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++; } void build_graph(int l,int r) { memset(head,-1,sizeof(head)); NE= 0; for(int i = 1; i <= n; i++) { for(int j = l; j <= r; j++) { addEdge(i,n+rank[i][j],inf); } } for(int i = 1; i <= n; i++) { addEdge(source,i,1); } for(int i = 1; i <= m; i++) { addEdge(i+n,sink,cap[i]); } } void search() { int l = 1,r = 1; int mid; int ans = m; build_graph(l,r); while(l <= r && r <= m) { mid = sap(source,sink); if(mid == n) { if(r - l + 1 < ans) ans = r - l + 1; l++; } else r++; build_graph(l,r); } printf("%d\n",ans); } int main() { while(scanf("%d%d",&n,&m) != EOF) { source = 0,sink = n + m + 1; NV = sink + 1; for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { scanf("%d",&rank[i][j]); } for(int i = 1; i <= m; i++) { scanf("%d",&cap[i]); } search(); } // system("pause"); return 0; } /* 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 */