Cod sursa(job #2126605)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 9 februarie 2018 19:19:22
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.36 kb
#include <bits/stdc++.h>
#define MAXN 605
#define INF 1000000000

#define BUF_SIZE 1 << 17
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
    if(pbuf==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buf[pbuf++];
}
inline int nextnum(){
    int a = 0, semn = 1;
    char c = nextch();
    while(!isdigit(c) && c != '-')
        c = nextch();
    if(c == '-') semn = -1, c = nextch();
    while(isdigit(c)){
        a = a * 10 + c - '0';
        c = nextch();
    }
    return a * semn;
}

int n, m, e, S, D, flux, total;
std::vector <int> G[1 + MAXN];
int C[1 + MAXN][1 + MAXN], Cost[1 + MAXN][1 + MAXN], I[1 + MAXN][1 + MAXN];
int father[1 + MAXN];

int q[1 + MAXN * MAXN], p, u, inq[1 + MAXN];
int dist[1 + MAXN];
inline void bellmanFord(){
    for(int i = 1; i <= n; i++) dist[i] = INF;
    p = u = 0;
    q[u++] = S, inq[S] = 1, dist[S] = 0;
    while(p < u){
        int node = q[p++];
        inq[node] = 0;
        for(auto y:G[node])
            if(C[node][y] && dist[y] > dist[node] + Cost[node][y]){
                dist[y] = dist[node] + Cost[node][y];
                if(!inq[y]) inq[y] = 1, q[u++] = y;
            }
    }
}

struct Edge{
    int dest, cost;
    bool operator < (const Edge &aux) const{return cost > aux.cost;}
};
int d[1 + MAXN], reald[1 + MAXN];
std::priority_queue <Edge> pq;
inline bool dijkstra(){
    memset(d, 0x3f, sizeof(d));
    d[S] = 0, reald[S] = 0;
    pq.push({S, 0});
    while(!pq.empty()){
        int node = pq.top().dest, cost = pq.top().cost;
        pq.pop();
        if(d[node] == cost){
            for(auto y: G[node])
                if(C[node][y]){
                    int newd = d[node] + Cost[node][y] + dist[node] - dist[y];
                    if(newd < d[y]){
                        d[y] = newd;
                        reald[y] = reald[node] + Cost[node][y];
                        father[y] = node;
                        pq.push({y, d[y]});
                    }
                }
        }
    }
    memcpy(dist, reald, sizeof(dist));
    return (d[D] != 0x3f3f3f3f);
}

int main(){
    fi = fopen("cmcm.in","r");
    fo = fopen("cmcm.out","w");

    n = nextnum(), m = nextnum(), e = nextnum();
    for(int i = 1; i <= e; i++){
        int x = nextnum(), y = nextnum(), cost = nextnum();
        I[x][n + y] = i;
        G[x].push_back(n + y);
        G[n + y].push_back(x);
        C[x][n + y]++;
        Cost[x][n + y] += cost;
        Cost[n + y][x] -= cost;
    }
    for(int i = 1; i <= n; i++){
        G[0].push_back(i);
        G[i].push_back(0);
        C[0][i]++;
    }
    for(int i = 1; i <= m; i++){
        G[n + m + 1].push_back(n + i);
        G[n + i].push_back(n + m + 1);
        C[n + i][n + m + 1]++;
    }

    S = 0, D = n + m + 1;
    bellmanFord();
    while(dijkstra()){
        int flow = INF, cost = 0;
        for(int i = D; i != S; i = father[i]) flow = std::min(flow, C[father[i]][i]), cost += Cost[father[i]][i];
        for(int i = D; i != S; i = father[i]) C[father[i]][i] -= flow, C[i][father[i]] += flow;
        total += cost * flow;
        flux += flow;
    }
    fprintf(fo,"%d %d\n", flux, total);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) if(!C[i][n + j] && I[i][n + j]) fprintf(fo,"%d ", I[i][n + j]);

    return 0;
}