P2053 [SCOI2007]修车

左边n个点 代表顾客 右边n*m个点 每n个为一组 (i,j)表示第i个维修工第k个修理该顾客的车

#include<bits/stdc++.h>
using namespace std;
const int INF = 0x7f7f7f7f;
const int MAXN = 1005, MAXM = 130000;
int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], f[MAXM << 1], mono[MAXM << 1], ed = 1, S, T;
int pre[MAXN];
bool exist[MAXN];
void addedge(int u, int v, int cap, int val)
{
    to[++ed] = v;
    nxt[ed] = Head[u];
    Head[u] = ed;
    f[ed] = cap;
    mono[ed] = val;
    to[++ed] = u;
    nxt[ed] = Head[v];
    Head[v] = ed;
    f[ed] = 0;
    mono[ed] = -1 * val;
    return;
}
bool BFS()
{
    int u;
    queue<int>q;
    memset(exist, false, sizeof(exist));
    memset(lev, 127, sizeof(lev));
    lev[S] = pre[S] = 0;
    q.push(S);
    while (q.size()) {
        u = q.front();
        q.pop();
        exist[u] = false;
        for (int i = Head[u]; i; i = nxt[i])
            if (f[i] && lev[u] + mono[i] < lev[to[i]]) {
                lev[to[i]] = lev[u] + mono[i];
                pre[to[i]] = i;
                if (!exist[to[i]]) {
                    exist[to[i]] = true;
                    q.push(to[i]);
                }
            }
    }
    memcpy(cur, Head, sizeof(Head));
    return lev[T] != INF;
}
int DFS(int u, int maxf)
{
    if (u == T || !maxf) {
        return maxf;
    }
    exist[u] = true;
    int cnt = 0;
    for (int &i = cur[u], tem; i; i = nxt[i])
        if (f[i] && lev[u] + mono[i] == lev[to[i]]) {
            if (exist[to[i]]) {
                continue;
            }
            tem = DFS(to[i], min(f[i], maxf));
            maxf -= tem;
            f[i] -= tem;
            f[i ^ 1] += tem;
            cnt += tem;
            if (!maxf) {
                break;
            }
        }
    if (!cnt) {
        lev[u] = -1 * INF;
    }
    exist[u] = false;
    return cnt;
}
int Augment()
{
    int delta = INF;
    for (int i = pre[T]; i; i = pre[to[i ^ 1]])
        if (f[i] < delta) {
            delta = f[i];
        }
    for (int i = pre[T]; i; i = pre[to[i ^ 1]]) {
        f[i] -= delta;
        f[i ^ 1] += delta;
    }
    return delta * lev[T];
}
int MCMF()
{
    int ans = 0;
    memset(exist, false, sizeof(exist));
    while (BFS())
        //ans+=DFS(S,INF)*lev[T];
    {
        ans += Augment();
    }
    return ans;
}
int t[100][65];
int main()
{
    int n, m;
    scanf("%d %d", &m, &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &t[j][i]);
        }
    }
    S = 0, T = n + n * m + 1;
    for (int i = 1; i <= n; i++) {
        addedge(S, i, 1, 0);
    }
    for (int i = n + 1; i <= n + n * m; i++) {
        addedge(i, T, 1, 0);
    }
    for (int i = 1; i <= n; i++) {
        for (int j = n + 1; j <= n + n * m; j++) {
            int x = (j - n - 1) / n + 1;
            int y = j - n - (x - 1) * n;
            addedge(i, j, 1, y * t[x][i]);
        }
    }
    double ans = MCMF() * 1.0 / n;
    printf("%.2f", ans);
    return 0;
}
View Code

 

posted @ 2019-04-09 20:58  Aragaki  阅读(140)  评论(0编辑  收藏  举报