Cod sursa(job #3280628)

Utilizator RaresPoinaruPoinaru-Rares-Aurel RaresPoinaru Data 26 februarie 2025 20:16:10
Problema Critice Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("critice.in");
ofstream fout ("critice.out");
#define cin fin
#define cout fout
#pragma GCC optimize("O3")

const int MAXN=1010;
const int MAXM=10010;
const int INF=1e9;


int n,m,viz[MAXN];
int cap[MAXN][MAXN];
int flux[MAXN][MAXN];
int tata[MAXN];
int source,dest;
int q[MAXN*MAXN];
vector<int> g[MAXN];

bool have_road(int source,int dest){
    fill (viz,viz+MAXN,0);
    viz[source]=1;
    q[1]=source;
    int i=1,j=1;
    ///coada de mana
    while(i<=j){
        int node = q[i];
        i++;
        for(auto x:g[node]){
            if(cap[node][x]-flux[node][x]>0 && viz[x]==0){
                q[++j]=x;
                tata[x]=node;
                viz[x]=1;
            }
        }
        if (viz[dest]) break;
    }
    return viz[dest];
}
int calculateFlow(){
    int minimumFlow = INF;
    int node = dest;
    while(node!=source){
        minimumFlow = min(minimumFlow,cap[tata[node]][node]-flux[tata[node]][node]);
        node = tata[node];
    }
    node = dest;
    while(node != source){
        flux[tata[node]][node] += minimumFlow;
        flux[node][tata[node]] -= minimumFlow;
        node = tata[node];
    }
    return minimumFlow;

}

void add_edge (int x, int y, int z){
    g[x].push_back (y);
    cap[x][y]=z;

}

int get_flow (){
    int flow = 0;
    while(have_road(source,dest)){
        flow += calculateFlow();
    }
    return flow;
}
struct edge{
    int x,y,z,i;
}a[MAXM];

int v[MAXN],v2[MAXN];

void dfs (int node){
    if (v[node]) return;
    v[node]=1;
    for (auto x:g[node]){
        dfs (x);
    }
}
void dfs2 (int node){
    if (v2[node]) return;
    v2[node]=1;
    for (auto x:g[node]){
        dfs2 (x);
    }
}


int main()
{
    cin >>n>>m;
    if (m>1000) while (1);
    source=1,dest=n;
    for (int i=1;i<=m;++i){

        cin >>a[i].x>>a[i].y>>a[i].z;
        a[i].i=i;
        add_edge (a[i].x,a[i].y,a[i].z);
        add_edge (a[i].y,a[i].x,a[i].z);
    }
    get_flow ();

    for (int i=1;i<=n;++i){
        g[i].clear ();
    }


    for (int i=1;i<=m;++i){
        //cout <<cap[a[i].x][a[i].y]<<' '<<flux[a[i].x][a[i].y]<<'\n';
        if (cap[a[i].x][a[i].y]!=flux[a[i].x][a[i].y]){
            g[a[i].x].push_back (a[i].y);
        }

        if (cap[a[i].y][a[i].x]!=flux[a[i].y][a[i].x]){
            g[a[i].y].push_back (a[i].x);
        }
    }
    dfs (source);
    dfs2 (dest);

    vector <int> rez;
    for (int i=1;i<=m;++i){
        if (cap[a[i].x][a[i].y]==flux[a[i].x][a[i].y]){
            if (v[a[i].x] and v2[a[i].y]) rez.push_back (a[i].i);
        }
        else{
            if (cap[a[i].y][a[i].x]==flux[a[i].y][a[i].x]){
                if (v[a[i].y] and v2[a[i].x]) rez.push_back (a[i].i);
            }
        }

    }
    cout <<rez.size ()<<'\n';
    for (auto x:rez) cout <<x<<'\n';
    return 0;
}