Cod sursa(job #2931116)

Utilizator ArseniuVictorStefanArseniu Victor Stefan ArseniuVictorStefan Data 30 octombrie 2022 15:58:37
Problema Critice Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <stdio.h>

#define NMAX 1'000
#define MMAX 10'000

struct edge
{
    int u, v;
};

int n, m, k;
int capacity[NMAX][NMAX], flow[NMAX][NMAX];
short g[NMAX][NMAX];
short index[MMAX], ptr[NMAX], level[NMAX], queue[NMAX], top;
edge edges[MMAX];

inline const int& min(const int& x, const int& y)
{
    return (x <= y ? x : y);
}

inline int cap(const int& u, const int& v)
{
    return capacity[u][v] - flow[u][v] - flow[v][u];
}

inline void add_flow(const int& u, const int& v, int fl)
{
    flow[u][v] += fl;
    int r = min(flow[u][v], flow[v][u]);
    flow[u][v] -= r; flow[v][u] -= r;
}

int dfs(int u, int fl)
{
    if(u == n - 1)
        return fl;
    
    for(; ptr[u] <= g[u][0]; ptr[u]++)
    {
        int v = g[u][ptr[u]];
        if(level[v] == level[u] + 1 && cap(u, v))
        {
            int crt = dfs(v, min(fl, cap(u, v)));
            if(crt)
            {
                add_flow(u, v, crt);
                return crt;
            }
        }
    }
    return 0;
}

bool bfs(int s, int t)
{
    for(int i = 0; i < n; i++)
        level[i] = -1;
    
    level[s] = 0;
    queue[0] = s;
    top = 1;
    for(int i = 0; i < top; i++)
    {
        int u = queue[i];
        for(int i = 1; i <= g[u][0]; i++)
        {
            int v = g[u][i];
            if(level[v] == -1 && cap(u, v) != 0)
            {
                level[v] = level[u] + 1;
                queue[top++] = v;
            }
        }
    }

    return level[t] != -1;
}

int main()
{
    freopen("critice.in", "r", stdin);
    freopen("critice.out", "w", stdout);

    scanf("%d %d", &n, &m);
    for(int i = 0; i < m; i++)
    {
        int u, v, w;
        scanf("%d %d %d", &u, &v, &w);
        u--; v--;
        edges[i] = { u, v };
        capacity[u][v] = capacity[v][u] = w;
        g[u][++g[u][0]] = v;
        g[v][++g[v][0]] = u;
    }

    int maxflow = 0;
    while(true)
    {
        if(!bfs(0, n - 1))
            break;

        for(int i = 0; i < n; i++)
            ptr[i] = 1;
        
        while(int flow = dfs(0, 0x3f3f3f3f))
            maxflow += flow;
    }

    for(int i = 0; i < m; i++)
    {
        if(cap(edges[i].u, edges[i].v) != 0)
            continue;

        capacity[edges[i].u][edges[i].v]++;
        capacity[edges[i].v][edges[i].u]++;

        if(bfs(0, n - 1))
            index[k++] = i + 1;

        capacity[edges[i].v][edges[i].u]--;
        capacity[edges[i].u][edges[i].v]--;
    }

    printf("%d\n", k);
    for(int i = 0; i < k; i++)
        printf("%d\n", index[i]);
    return 0;
}