Cod sursa(job #3302740)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 10 iulie 2025 14:01:57
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.55 kb
// Ilie "The-Winner" Dumitru
// Dumnezeu sa o ierte
#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using ll=long long;
constexpr int NMAX=1024;
constexpr ll MOD=1000000007;

struct Dinic {
	struct Edge {
		int to, rev;
		ll c, oc;
		ll flow() { return std::max(oc - c, 0LL); } // if you need flows
	};
	std::vector<int> lvl, ptr, q;
	std::vector<std::vector<Edge> > adj;
	Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
	void addEdge(int a, int b, ll c, ll rcap = 0) {
		adj[a].push_back({b, sz(adj[b]), c, c});
		adj[b].push_back({a, sz(adj[a]) - 1, rcap, rcap});
	}
	ll dfs(int v, int t, ll f) {
		if (v == t || !f) return f;
		for (int& i = ptr[v]; i < sz(adj[v]); i++) {
			Edge& e = adj[v][i];
			if (lvl[e.to] == lvl[v] + 1)
				if (ll p = dfs(e.to, t, std::min(f, e.c))) {
					e.c -= p, adj[e.to][e.rev].c += p;
					return p;
				}
		}
		return 0;
	}
	ll calc(int s, int t) {
		ll flow = 0; q[0] = s;
		for(int L=0;L<31;++L) do { // 'int L=30' maybe faster for random data
			lvl = ptr = std::vector<int>(sz(q));
			int qi = 0, qe = lvl[s] = 1;
			while (qi < qe && !lvl[t]) {
				int v = q[qi++];
				for (Edge e : adj[v])
					if (!lvl[e.to] && e.c >> (30 - L))
						q[qe++] = e.to, lvl[e.to] = lvl[v] + 1;
			}
			while (ll p = dfs(s, t, LLONG_MAX)) flow += p;
		} while (lvl[t]);
		return flow;
	}
	bool leftOfMinCut(int a) { return lvl[a] != 0; }
};


struct edge
{
	int a, b;
};

int N, M;
std::vector<edge> E;
std::bitset<NMAX> reach[2];

void bfs(Dinic& D, int src, std::bitset<NMAX>& reach, bool checkBack=0)
{
	std::queue<int> q;
	int node;

	reach[src]=1;
	for(q.push(src);!q.empty();)
	{
		node=q.front();
		q.pop();

		for(auto e : D.adj[node])
			if(!reach[e.to])
			{
				if((checkBack && D.adj[e.to][e.rev].c) || (!checkBack && e.c))
				{
					q.push(e.to);
					reach[e.to]=1;
				}
			}
	}
}

int main()
{
	FILE* f=fopen("critice.in", "r"), *g=fopen("critice.out", "w");
	int i, a, b, w;

	fscanf(f, "%d%d", &N, &M);
	Dinic D(N);
	for(i=0;i<M;++i)
	{
		fscanf(f, "%d%d%d", &a, &b, &w);
		--a;
		--b;
		E.push_back({a, b});
		D.addEdge(a, b, w, w);
	}

	D.calc(0, N-1);

	bfs(D, 0, reach[0]);
	bfs(D, N-1, reach[1], 1);

	// for(i=0;i<N;++i)
		// printf("%d", (int)reach[0][i]);
	// printf("\n");
	// for(i=0;i<N;++i)
		// printf("%d", (int)reach[1][i]);
	// printf("\n");

	std::vector<int> sol;
	for(i=0;i<M;++i)
		if((reach[0][E[i].a] && reach[1][E[i].b]) || (reach[0][E[i].b] && reach[1][E[i].a]))
			sol.push_back(i+1);

	fprintf(g, "%d\n", sz(sol));
	for(int x : sol)
		fprintf(g, "%d\n", x);

	fclose(f);
	fclose(g);
	return 0;
}