Cod sursa(job #2690938)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 26 decembrie 2020 14:44:06
Problema Critice Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.76 kb
#include <bits/stdc++.h>

using namespace std;

class InParser {
	
private:
	
	FILE *fin;
	
	char *buff;
	
	int sp;
	
 
	
	char read_ch() {
	
		++sp;
	
		if (sp == 4096) {
	
			sp = 0;
	
			fread(buff, 1, 4096, fin);
	
		}
	
		return buff[sp];
	
	}
	
 
	
public:
	
	InParser(const char* nume) {
	
		fin = fopen(nume, "r");
	
		buff = new char[4096]();
	
		sp = 4095;
	
	}
	
	
	
	InParser& operator >> (int &n) {
	
		char c;
	
		while (!isdigit(c = read_ch()) && c != '-');
	
		int sgn = 1;
	
		if (c == '-') {
	
			n = 0;
	
			sgn = -1;
	
		} else {
	
			n = c - '0';
	
		}
	
		while (isdigit(c = read_ch())) {
	
			n = 10 * n + c - '0';
	
		}
	
		n *= sgn;
	
		return *this;
	
	}
	
	
	
	InParser& operator >> (long long &n) {
	
		char c;
	
		n = 0;
	
		while (!isdigit(c = read_ch()) && c != '-');
	
		long long sgn = 1;
	
		if (c == '-') {
	
			n = 0;
	
			sgn = -1;
	
		} else {
	
			n = c - '0';
	
		}
	
		while (isdigit(c = read_ch())) {
	
			n = 10 * n + c - '0';
	
		}
	
		n *= sgn;
	
		return *this;
	
	}
	
};

class Graph{
    int source, dest, n;
    vector < vector <int> > capacity;
    vector < vector <int> > adj;
    vector < int > parent;
    vector < bool > vis;
    vector < pair <int, int> > edges;

    void dfs(int node = 1) {
        vis[node] = true;
        for (auto&it : adj[node])
            if (!vis[it] and capacity[node][it])
                dfs(it);
    }

    bool bfs() {
        fill(vis.begin(), vis.end(), false);

        int node = source;
        vis[node] = true;
        queue <int> q;
        q.push(node);

        while (!q.empty()) {
            node = q.front();
            q.pop();

            for (auto& it : adj[node])
                if (!vis[it] and capacity[node][it]) {
                    vis[it] = true;
                    parent[it] = node;
                    q.push(it);
                }
        }

        return vis[dest];
    }

    int max_flow() {
        int maxflow = 0;

        while (bfs()) {
            for (auto& it : adj[dest]) 
                if (vis[it] and capacity[it][dest]) {
                    parent[dest] = it;
                    int flow = INT_MAX;

                    for (int node = dest; node != source; node = parent[node])
                        flow = min(flow, capacity[parent[node]][node]);

                    for (int node = dest; node != source; node = parent[node]) {
                        capacity[parent[node]][node] -= flow;
                        capacity[node][parent[node]] += flow;
                    }

                    maxflow += flow;
                }
        }

        return maxflow;
    }

public:
    Graph(int n, int source, int dest) : n(n), source(source), dest(dest), adj(n + 1), 
                                        capacity(n + 1, vector <int>(n + 1)), parent(n + 1), vis(n + 1) {}

    void add_edge(int node1, int node2, int cap = 1) {
        adj[node1].push_back(node2);
        adj[node2].push_back(node1);
        capacity[node1][node2] = capacity[node2][node1] = cap;
        edges.push_back({node1, node2});
    }

    vector <int> critice() {
        max_flow();
        // fill(vis.begin(), vis.end(), false);
        // dfs();

        vector <int> ans;

        for (int i = 0; i < edges.size(); i++) {
            if (vis[edges[i].first] != vis[edges[i].second]) 
                ans.push_back(i + 1);
        }

        return ans;
    }
};

int main() {
    InParser cin("critice.in");
    ofstream cout("critice.out");
    // ifstream cin("input.txt");
    // ofstream cout("output.txt");

    int n, m;
    cin >> n >> m;
    Graph G(n, 1, n);

    for (int i = 1; i <= m; ++i) {
        int x, y, z;
        cin >> x >> y >> z;
        G.add_edge(x, y, z);
    }

    auto ans = G.critice();   
    cout << ans.size() << '\n';
    for (auto& it : ans)
        cout << it << '\n';

    return 0;
}