P2857 [USACO06FEB]稳定奶牛分配Steady Cow Assignment 最大流

  有N头牛,B个牛棚.告诉你每头牛心里牛棚的座次,即哪个牛棚他最喜欢,哪个第2喜欢, 哪个第3喜欢,等等.但牛棚容量一定,所以每头牛分配到的牛棚在该牛心中的座次有高有低.现 在求一种最公平的方法分配牛到牛棚,使所有牛中,所居牛棚的座次最高与最低的跨度最小.

 

枚举最大和最小的座次  然后连图看看能不能行

P2857 [USACO06FEB]稳定奶牛分配Steady Cow Assignment  最大流
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=4e5+44;
const int M=4e6+54;

struct edge {
    int to, next, w;
} e[M << 1];
int head[N], cnt = 1;
void add(int x, int y, int z) {
    e[++cnt] = (edge){y, head[x], z};
    head[x] = cnt;
    e[++cnt] = (edge){x, head[y], 0};
    head[y] = cnt;
}
int level[N];
bool bfs(int s, int t) {
    memset(level, 0, sizeof level);
    queue<int> q;
    level[s] = 1;
    q.push(s);
    while (!q.empty()) {
        int pos = q.front();
        q.pop();
        for (int i = head[pos]; i; i = e[i].next) {
            int nx = e[i].to;
            if (!e[i].w || level[nx]) continue;
            level[nx] = level[pos] + 1;
            q.push(nx);
        }
    }
    return level[t];
}
int dfs(int s, int t, int flow) {
    if (s == t) return flow;
    int ret = 0;
    for (int i = head[s]; flow && i; i = e[i].next) {
        int nx = e[i].to;
        if (level[nx] == level[s] + 1 && e[i].w) {
            int tmp = dfs(nx, t, min(flow, e[i].w));
            e[i].w -= tmp;
            e[i ^ 1].w += tmp;
            flow -= tmp;
            ret += tmp;
        }
    }
    if (!ret) level[s] = 0;
    return ret;
}
int dinic(int s, int t) {
    int ret = 0;
    while (bfs(s, t)) ret += dfs(s, t, inf);
    return ret;
}

int n,m,s,t;
void init()
{
    CLR(head,0);cnt=1;
}
int a[1000+5][30];
int num[N];
void build(int x,int y)
{
    init();
    rep(i,1,m)
    add(s,i,num[i]);

    rep(i,1,n)
    rep(j,x,y)
    {
        add(a[i][j],i+m,1);
    }
    rep(i,1,n)
    add(i+m,t,1);
}
int main()
{
    RII(n,m);
    rep(i,1,n)rep(j,1,m)RI(a[i][j]);
    rep(i,1,m)
    RI(num[i]);
    s=n+m+1;t=s+1;

    int ans=inf;
    rep(i,0,m)
    rep(j,1,m)
    {
        int e=j+i;if(e>m)continue;
        build(j,e);
        if(dinic(s,t)==n)
            {ans=min(ans,e-j+1);break;}
    }
    cout<<ans;

    return 0;
}
View Code

 

上一篇:BZOJ 1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏 幼儿园测试题


下一篇:母牛的故事