Cod sursa(job #1118975)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 24 februarie 2014 14:10:13
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;

#define Nmax 1005
#define Mmax 10005

vector <int> graph[Nmax];
int c[Nmax][Nmax], f[Nmax][Nmax];
int U[Mmax], V[Mmax];
int S[Nmax], T[Nmax], sol[Mmax];
int ft[Nmax];
int n, m, s, t, flow;

void read(){
	freopen("critice.in", "r", stdin);
	int u, v, cc;

	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; ++i){
		scanf("%d %d %d", &u, &v, &cc);
		c[u][v] += cc;
		c[v][u] += cc;
		graph[u].push_back(v);
		graph[v].push_back(u);
		U[i] = u;
		V[i] = v;

	}
	s = 1;
	t = n;
	fclose(stdin);
}

int min(int a, int b){
	if (a < b)
		return a;
	return b;
}

int bfs(){
    vector <int>::iterator it;
    queue <int> q;
    int u;

    for (int i = 1; i <= n; ++i)
		ft[i] = 0;
	q.push(s);

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

		for (it = graph[u].begin(); it != graph[u].end(); ++it)
			if (!ft[*it] && c[u][*it] != f[u][*it]){
				ft[*it] = u;
				q.push(*it);
			}
	}
	return ft[t];
}

void dinic(){
	vector <int>::iterator it;
	int f_min;

	while ( bfs() ){
		for (it = graph[t].begin(); it != graph[t].end(); ++it)
			if (ft[*it] && c[*it][t] != f[*it][t]){
				f_min = c[*it][t] - f[*it][t];
				for (int i = *it; i != s; i = ft[i])
					f_min = min(f_min, c[ ft[i] ][i] - f[ ft[i] ][i]);

				f[*it][t] += f_min;
				f[t][*it] -= f_min;
				for (int i = *it; i != s; i = ft[i]){
					f[ ft[i] ][i] += f_min;
					f[i][ ft[i] ] -= f_min;
				}
			}
	}
}

void dfs(int u, int a[]){
	vector <int>::iterator it;
	a[u] = 1;

	for (it = graph[u].begin(); it != graph[u].end(); ++it)
		if (!a[*it] && c[u][*it] != f[u][*it] && c[*it][u] != f[*it][u])
			dfs(*it, a);
}

void write(){
	freopen("critice.out", "w", stdout);
	int k = 0;
	for (int i = 1; i <= m; ++i)
		if ( (S[ U[i] ] && T[ V[i] ]) || (S[ V[i] ] && T[ U[i] ]) )
			sol[k++] = i;

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

int main(){
	// dupa aflarea flowului maxim in graf, parcurgem muchiile printr-un dfs, odata din nodul sursa si odata din nodul destinatie
	// o muchie poate fi traversata doar daca mai poate fi augmentata.
	// fiecare drum de la sursa la destinatie are cel putin o muchie critica
	// daca dupa parcurgeri am ajuns la ambele capete ale unei muchii atunci aceasta este singura muchie critica de pe un drum
	read();
	dinic();
	dfs(s, S);
	dfs(t, T);
	write();

	return 0;
}