[SCOI2007] repair solution to a problem

Elder network flow problem

In order to facilitate consideration of the contribution of each decision, the decision of each worker split into N mutually independent decision-making: that is what their penultimate i repair a car yes. Because after the car (with the car) there are people i have to wait T, so the contribution to T * n

This split point map building to contribute to the running costs (bipartite graph) cost flow can be seen from the flow properties of the repair cost per person will be lawful order

Note that this problem N, M bit unusual sequence

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int maxn=400005;
const int inf = 0x3f3f3f3f;
int n, m, maxflow, mincost;

struct gra {
    int tm, st[maxn], to[maxn], nx[maxn], c[maxn], d[maxn];
    int dis[maxn], inq[maxn], flow[maxn];
    int pre[maxn], last[maxn];
    queue <int> q;
    void cle() {
        tm=-1;
        memset(st, -1, sizeof(st));
    }
    void adde(int a, int b, int cc, int dd) {
        //cout<<a<<' '<<' '<<b<<' '<<cc<<' '<<dd<<endl;;
        tm++;
        nx[tm]=st[a];
        st[a]=tm;
        to[tm]=b;
        c[tm]=cc;
        d[tm]=dd;
        
        tm++;=
        NX [TM]st[b];
        st[b]=tm;
        to[tm]=a;
        c[tm]=0;
        d[tm]=-dd;
    }
    bool spfa(int s, int t) {
        memset(dis, 0x3f, sizeof(dis));
        memset(inq, 0, sizeof(inq));
        memset(flow, 0, sizeof(flow));
        memset(pre, 0, sizeof(pre));
        memset(last, 0, sizeof(last));
        flow[s]=inf;
        int x, y, i;
        q.push(s); inq[s]=1;
        dis[s]=0; pre[t]=-1;
        while(!q.empty()) {
            x=q.front();
            q.pop();
            inq[x]=0;
            for(i=st[x]; i != -1; i=nx[i]) {
                y=to[i];
                if(c[i] > 0 && dis[y] > dis[x]+d[i]) {
                    dis[y] = dis[x]+d[i];
                    pre[y]=x;
                    last[y]=i;
                    flow[y]=min(flow[x], c[i]);
                    if(!inq[y]) {
                        inq[y]=1; q.push(y);
                    }
                }
            }
        }
        return (pre[t] != -1);
    }
    void count(int s, int t) {
        int x;
        while(spfa(s, t)) {
            int x=t;
            maxflow+=flow[t];
            mincost+=flow[t]*dis[t];
            while(x != s) {
                c[last[x]]-=flow[t];
                c[(last[x]^1)]+=flow[t];
                x=pre[x];
            }
        }
        return;
    }
} G;

int main() {
    ios::sync_with_stdio(false);
    G.cle();
    double ans;
    int i, j, ta, tb, tc, td, S, T, k;
    cin>>n>>m;
    S=n*m+m+1; T=n*m+m+2;
    for(i=1; i <= n*m; i++) G.adde(S, i, 1, 0);
    for(i=1; i <= m; i++) G.adde(i+n*m, T, 1, 0);
    for(i=1; i <= m; i++) {
        for(j=1; j <= n; j++) {
            cin>>ta;
            for(k=1; k <= m; k++) 
                G.adde(m*(j-1)+k, i+n*m, 1, ta*k);
        }
    }
    G.count(S, T);
    ans=(mincost*1.0)/m;
    printf("%.2lf\n", ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/crraphael/p/11346226.html