Pagini recente » Cod sursa (job #2575504) | Cod sursa (job #1336318) | Cod sursa (job #2613028) | Cod sursa (job #2202728) | Cod sursa (job #1261825)
#include <bits/stdc++.h>
using namespace std;
const int Nmax = 100005, Mmax = Nmax * 3;
struct Point {
double x, y;
};
Point points[Nmax];
pair<int, int> edges[Mmax], Pos[Mmax];
int Capacity[Mmax];
vector<int> G[Nmax], Gz[Mmax];
int Zone[Mmax][2], Color[Mmax];
int deg[Mmax];
bitset<Mmax> used;
int getZones(int N, int M) {
int czones = 0;
for (int i = 1; i <= N; ++i) {
sort(G[i].begin(), G[i].end(), [i](const int a, const int b) {
int node1 = edges[a].first ^ edges[a].second ^ i;
int node2 = edges[b].first ^ edges[b].second ^ i;
return atan2(points[node1].y - points[i].y, points[node1].x - points[i].x) < atan2(points[node2].y - points[i].y, points[node2].x - points[i].x);
});
for (int j = 0; j < int(G[i].size()); ++j) {
int p = G[i][j];
(i == edges[p].first ? Pos[p].first: Pos[p].second) = j;
}
}
for (int i = 1; i <= M; ++i) {
for (int j = 0; j < 2; ++j) {
if (Zone[i][j]) continue;
czones++;
int goodSign = j == 0 ? -1: 1, k, lastNode, lastOther, start = edges[i].first;
for (k = i, lastNode = edges[i].second, lastOther = edges[i].first; lastNode != start;) {
if (Zone[k][lastNode == edges[k].second ? j: (j ^ 1)]) break;
Zone[k][lastNode == edges[k].second ? j: (j ^ 1)] = czones;
int goodEdge = G[lastNode][((lastNode == edges[k].second ? Pos[k].second: Pos[k].first) + goodSign + G[lastNode].size()) % G[lastNode].size()];
int node = lastNode ^ edges[goodEdge].second ^ edges[goodEdge].first;
int other = edges[goodEdge].first ^ edges[goodEdge].second ^ node;
k = goodEdge;
lastNode = node;
lastOther = other;
}
if (!Zone[k][lastNode == edges[k].second ? j: (j ^ 1)])
Zone[k][lastNode == edges[k].second ? j: (j ^ 1)] = czones;
}
}
assert(czones == 2 + M - N);
return czones;
}
void buildZoneGraph(int N, int M, int czones) {
for (int i = 1; i <= M; ++i) {
Gz[Zone[i][0]].push_back(Zone[i][1]);
Gz[Zone[i][1]].push_back(Zone[i][0]);
}
for (int i = 1; i <= czones; ++i) {
sort(Gz[i].begin(), Gz[i].end());
Gz[i].erase(unique(Gz[i].begin(), Gz[i].end()), Gz[i].end());
}
}
void colorNewGraph(int N) {
vector<int> order;
order.reserve(N);
for (int i = 1; i <= N; ++i) {
deg[i] = Gz[i].size();
if (deg[i] < 6) {
order.push_back(i);
used[i] = 1;
}
}
for (int i = 0; i < N; ++i) {
int node = order[i];
for (int p: Gz[node]) {
deg[p]--;
if (!used[p] && deg[p] < 6) {
used[p] = 1;
order.push_back(p);
}
}
}
reverse(order.begin(), order.end());
for (int node: order) {
char usedCol = 0;
for (int p: Gz[node])
usedCol |= 1 << Color[p];
for (int i = 1; ; ++i) {
if (!(usedCol & (1 << i))) {
Color[node] = i;
break;
}
}
}
}
void setEdges(int N, int M) {
for (int i = 1; i <= M; ++i) {
Capacity[i] = Color[Zone[i][1]] - Color[Zone[i][0]];
if (Capacity[i] < 0) {
Capacity[i] = -Capacity[i];
swap(edges[i].first, edges[i].second);
}
}
}
void writeAnswer(int N, int M) {
for (int i = 1; i <= M; ++i)
printf("%d %d %d\n", edges[i].first, edges[i].second, Capacity[i]);
}
int main()
{
freopen("nowhere-zero.in", "r", stdin);
freopen("nowhere-zero.out", "w", stdout);
int N, M;
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; ++i)
scanf("%lf%lf", &points[i].x, &points[i].y);
for (int i = 1; i <= M; ++i) {
scanf("%d%d", &edges[i].first, &edges[i].second);
G[edges[i].first].push_back(i);
G[edges[i].second].push_back(i);
}
int czones = getZones(N, M);
buildZoneGraph(N, M, czones);
colorNewGraph(czones);
setEdges(N, M);
writeAnswer(N, M);
}