Pagini recente » Cod sursa (job #1018288) | Cod sursa (job #1613526) | Cod sursa (job #1476518) | Cod sursa (job #1323918) | Cod sursa (job #959448)
Cod sursa(job #959448)
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
#define MaxN 100100
#define sqr(x) ((x) * (x))
struct Edge {
int vec, flux;
Edge(int v) {
vec = v;
flux = 0;
}
};
pair<double, double> points[MaxN];
int N, M, doneEdges = 0;
vector<Edge> edges[MaxN];
int cd[MaxN], t[MaxN];
bool viz[MaxN], haveTouched[MaxN];
int startNode = 0, sizeCd = 0;
bool stillCycling;
void SetTata(int poz, int val) {
t[poz] = val;
cd[sizeCd++] = poz;
}
void ClearTati() {
for (int i = 0; i < sizeCd; i++) {
t[cd[i]] = -1;
}
sizeCd = 0;
}
bool CompFlux(const Edge &a, const Edge &b) {
return a.flux < b.flux;
}
double GetDist(int x, const Edge &a) {
const int y = a.vec;
return sqrt(sqr(points[x].first - points[y].first) + sqr(points[x].first - points[y].first));
}
bool CompFluxDist(const Edge &a, const Edge &b) {
if (a.flux != b.flux) {
return a.flux < b.flux;
} else {
return GetDist(startNode, a) < GetDist(startNode, b);
}
}
void IncremFlow(int x, int y, int flux) {
for (size_t i = 0; i < edges[x].size(); i++) {
if (edges[x][i].vec == y) {
doneEdges += (edges[x][i].flux == 0 && flux > 0);
edges[x][i].flux += flux;
return;
}
}
}
void MarkEdge(int x, int y) {
IncremFlow(x, y, 1);
IncremFlow(y, x, -1);
}
bool HaveEdges(int x) {
for (size_t i = 0; i < edges[x].size(); i++) {
if (edges[x][i].flux == 0) {
return true;
}
}
return false;
}
void ReversePath(int nod) {
MarkEdge(nod, startNode);
while (nod != startNode) {
MarkEdge(t[nod], nod);
nod = t[nod];
}
}
void df(int nod) {
sort(edges[nod].begin(), edges[nod].end(), CompFluxDist);
for (int i = 0; i < (int)edges[nod].size() && stillCycling; i++) {
const int vec = edges[nod][i].vec;
if (edges[nod][i].flux >= 0 && t[vec] == -1 && vec != t[nod]) {
if (vec == startNode) {
stillCycling = false;
ReversePath(nod);
return;
}
SetTata(vec, nod);
df(vec);
}
}
}
void FindCycle() {
while (!HaveEdges(startNode) && startNode < N) {
startNode++;
}
stillCycling = true;
for (size_t i = 0; i < edges[startNode].size(); i++) {
if (edges[startNode][i].flux == 0) {
const int v = edges[startNode][i].vec;
SetTata(v, startNode);
df(v);
ClearTati();
return;
}
}
}
int main() {
freopen("nowhere-zero.in", "rb", stdin);
freopen("nowhere-zero.out", "wb", stdout);
scanf("%d %d\n", &N, &M);
for (int i = 0; i < N; i++) {
scanf("%lf %lf", &points[i].first, &points[i].second);
}
for (int i = 0; i < M; i++) {
int x, y;
scanf("%d %d", &x, &y);
x--; y--;
edges[x].push_back(y);
edges[y].push_back(x);
}
memset(t, -1, sizeof(int) * N);
while (doneEdges < M) {
FindCycle();
}
for (int i = 0; i < N; i++) {
for (size_t j = 0; j < edges[i].size(); j++) {
if (edges[i][j].flux > 0) {
printf("%d %d %d\n", i + 1, edges[i][j].vec + 1, edges[i][j].flux);
}
}
}
return 0;
}