【USACO 2857】 Steady Cow Assignment

【题目链接】

            点击打开链接

【算法】

           二分答案,check的时候跑最大流,即可

【代码】

         

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2000
#define MAXB 1000

int i,j,low,high,mid,st,ed,N,B,tot,ans,tmp;
int h[MAXN+MAXB],U[MAXN*MAXB],V[MAXN*MAXB],
   W[MAXN*MAXB],Head[MAXN*MAXB],Next[MAXN*MAXB],
     other[MAXN*MAXB],v[MAXB+10],a[MAXN+10][MAXB+10];
     
template <typename T> void read(T &x) {
        int f=1; char c = getchar(); x=0;
        for (; !isdigit(c); c = getchar()) { if (c=='-') f = -f; }
        for (; isdigit(c); c = getchar()) x=x*10+c-'0';
        x*=f;
}
template <typename T> inline void write(T x) {
        if (x < 0) { putchar('-'); x = -x; }
        if (x > 9) write(x/10);
        putchar(x % 10 + '0');    
}

template <typename T> inline void writeln(T x) {
        write(x);
        puts("");    
}

inline void add(int a,int b,int c) {
        ++tot;
        U[tot] = a; V[tot] = b; W[tot] = c;
        Next[tot] = Head[a]; Head[a] = tot; 
        other[tot] = ++tot;
        U[tot] = b; V[tot] = a; W[tot] = 0;
        Next[tot] = Head[b]; Head[b] = tot;
        other[tot] = tot - 1;    
}

inline bool bfs() {
        int i,x,y;
        queue<int> q;
        memset(h,0,sizeof(h));
        h[st] = 1; q.push(st);
        while (!q.empty()) {
                x = q.front(); q.pop();
                for (i = Head[x]; i; i = Next[i]) {
                        y = V[i];
                        if ((W[i] > 0) && (!h[y])) {
                                h[y] = h[x] + 1;
                                q.push(y);
                        }
                }
        }
        if (h[ed]) return true;
        else return false;
}

inline int maxflow(int x,int f) {
        int i,t,y,sum=0;
        if (x == ed) return f;
        for (i = Head[x]; i; i = Next[i]) {
                y = V[i];
                if ((W[i] > 0) && (h[y] == h[x] + 1) && (sum < f)) {
                        sum += (t = maxflow(y,min(W[i],f-sum)));
                        W[i] -= t; W[other[i]] += t;
                }     
        }    
        if (!sum) h[x] = 0;
        return sum;
}

inline bool check(int ml) {
        int i,j,l,r,sum;    
        for (l = 1; l <= N - ml + 1; l++) {
                r = l + ml - 1;
                for (i = 1; i <= tot; i++) Head[i] = 0;
                tot = 0;
                for (i = 1; i <= N; i++) add(st,i,1);
                for (i = 1; i <= B; i++) add(i+N,ed,v[i]);
                for (i = 1; i <= N; i++) {
                        for (j = 1; j <= B; j++) {
                                if ((a[i][j] >= l) && (a[i][j] <= r))
                                        add(i,j+N,1);
                        }
                }
                sum = 0;
                while (bfs()) {
                        sum += maxflow(st,N);
                }
                if (sum == N) return true;
        }
        return false;
}

int main() {
        
        read(N); read(B);
        st = N + B + 1; ed = st + 1;
        
        for (i = 1; i <= N; i++) {
                for (j = 1; j <= B; j++) {
                        read(tmp);
                        a[i][tmp] = j;
                }    
        } 
        for (i = 1; i <= B; i++) read(v[i]);
        
        low = 0; high = B;
        while (low <= high) {
                mid = (low + high) / 2;
                if (check(mid)) {
                        high = mid - 1;
                        ans = mid;
                } else 
                        low = mid + 1;
        }
        writeln(ans);
        
        return 0;
    
} 

 

posted @ 2018-04-18 19:54  evenbao  阅读(215)  评论(0编辑  收藏  举报