Cod sursa(job #3302742)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 10 iulie 2025 14:11:31
Problema Critice Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 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;

template<class F=ll> struct Dinic {
	struct Edge { int to, rev; F c, oc; F flow() {
		return std::max(oc-c, (F)0); } /* 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;
		// 'int L=30' maybe faster for random data
		for(int L=0;L<31;++L) do { 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<ll>& 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;
}