您的位置:首页 > 其它

[BZOJ1070] [SCOI2007]修车 && 二分图最佳完美匹配 或 费用流

2015-03-23 22:22 423 查看
首先是二分图匹配的代码 把等待时间设置为负值 求最大匹配

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define min(x, y) ((x) < (y) ? (x) : (y))
using namespace std;
typedef long long LL;
const int MAXN = 9;
const int MAXM = 60;
const int INF = 0x3f3f3f3f;
int n, m;
struct Node {
    int v, wt;
    Node () {}
    Node (int a, int b) : v(a), wt(b) {}
} ;
template <int maxn>
struct K_M {
    int n, m;
    vector <Node> G[maxn+10];
    int Lx[maxn+10], Ly[maxn+10], slack[maxn+10], Left[maxn+10];
    bool S[maxn+10], T[maxn+10];
    void add(int u, int v, int wt) { G[u].push_back(Node(v, wt)); }
    int Match(int u) {
        S[u] = true;
        for(int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v, wt = G[u][i].wt;
            if(Lx[u] + Ly[v] == wt && !T[v]) {
                T[v] = true;
                if(!Left[v] || Match(Left[v])) {
                    Left[v] = u;
                    return 1;
                }
            }
            slack[v] = min(Lx[u] + Ly[v] - wt, slack[v]);
        }
        return 0;
    }
    void Update() {
        int a = INF;
        for(int i = 1; i <= m; i++) if(!T[i]) a = min(a, slack[i]);
        for(int i = 1; i <= n; i++) if(S[i]) Lx[i] -= a;
        for(int i = 1; i <= m; i++) 
            if(T[i]) Ly[i] += a;
            else slack[i] -= a;
    }
    int BestMatch(int _n, int _m) {
        int ans = 0;
        n = _n; m = _m;
        for(int i = 1; i <= n; i++) {
            memset(slack, 0x3f, sizeof(slack));
            while(true) {
                memset(S, 0, sizeof(S));
                memset(T, 0, sizeof(T));
                if(Match(i)) break;
                else Update();
            }
        }
        for(int i = 1; i <= m; i++) ans += Lx[Left[i]] + Ly[i];
        return -ans;
    }
};
K_M <MAXN * MAXM> KM;
int main() 
{
    SF("%d%d", &m, &n);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) {
            int x; SF("%d", &x);
            for(int k = 1; k <= n; k++)
                KM.add(i, (j-1) * n + k, -x * k);
        }
    int ans = KM.BestMatch(n, n*m);
    PF("%.2f", 1.0 * ans / n);
}


费用流代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 1000;
const int INF = 0x3f3f3f3f;
int n, m, S, T, k;
int t[100][100];
struct Node {
    int u, v, c, cost;
    Node () {}
    Node (int a, int b, int C, int d) : u(a), v(b), c(C), cost(d) {}
} ;
template <int maxn>
struct MCMF {
    int n, m, s, t;
    vector <Node> Edge;
    vector <int> G[maxn+10];
    int inq[maxn+10], a[maxn+10], p[maxn+10], d[maxn+10];
    void add(int u, int v, int c, int wt) {
        Edge.push_back(Node(u, v, c, wt));
        Edge.push_back(Node(v, u, 0, -wt));
        m = Edge.size();
        G[u].push_back(m-2); G[v].push_back(m-1);
    }
    bool SPFA(int s, int t, int &Flow, int &Cost) {
        queue <int> q;
        memset(d, 0x3f, sizeof(d));
        for(int i = 1; i <= t; i++) inq[i] = 0;
        d[s] = 0; a[s] = INF; p[s] = 0; inq[s] = 1;
        q.push(s);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            inq[u] = 0;
            for(int i = 0; i < G[u].size(); i++) {
                Node &e = Edge[G[u][i]];
                int v = e.v, c = e.c, wt = e.cost;
                if(c && d[v] > d[u] + wt) {
                    d[v] = d[u] + wt;
                    a[v] = min(a[u], c);
                    p[v] = G[u][i];
                    if(!inq[v]) inq[v] = true, q.push(v);
                }
            }
        }
        if(d[t] == INF) return false;
        Flow += a[t];
        Cost += d[t];
        int u = t;
        while(u != s) {
            Edge[p[u]].c -= a[t];
            Edge[p[u]^1].c += a[t];
            u = Edge[p[u]].u;
        }
        return true;
    }
    int Mincost (int s, int t) {
        int Flow = 0, Cost = 0;
        while(SPFA(s, t, Flow, Cost)) 
            ;
        return Cost;
    }
} ;
MCMF <MAXN> sap;
int main()
{
    SF("%d%d", &m, &n);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            SF("%d", &t[i][j]);
    S = n + n * m + 1; T = S + 1;
    sap.n = T;
    for(int i = 1; i <= n; i++) sap.add(S, i, 1, 0);
    for(int i = n+1; i <= n+n*m; i++) sap.add(i, T, 1, 0);
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
            for(int k = 1; k <= n; k++)
                sap.add(k, n+n*(i-1)+j, 1, t[k][i] * j);
    int ans = sap.Mincost(S, T);
    PF("%.2f", 1.0*ans/n);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: