Pagini recente » Istoria paginii runda/aaaaa | Cod sursa (job #2051094) | Cod sursa (job #644509) | Cod sursa (job #697802) | Cod sursa (job #1743698)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
using namespace std;
ifstream cin("nowhere-zero.in");
ofstream cout("nowhere-zero.out");
const int MAXN = 100100;
int n, m, pivot;
int regions = 0;
double X[1 + MAXN], Y[1 + MAXN];
vector<pair<int, int> > g[1 + MAXN];
vector<int> graph[1 + 3 * MAXN], order;
vector<bool> usedEdge[1 + MAXN];
map<int, int> edgeIndex[1 + MAXN];
pair<int, int> orientation[1 + 3 * MAXN], region[1 + 3 * MAXN];
set<pair<int, int> > Set;
int color[1 + 3 * MAXN], degree[1 + 3 * MAXN];
bool seen[1 + 3 * MAXN], usedColor[7];
bool Compare(const pair<int, int> &a, const pair<int, int> &b) {
return atan2(Y[a.first] - Y[pivot], X[a.first] - X[pivot]) < atan2(Y[b.first] - Y[pivot], X[b.first] - X[pivot]);
}
void ComputeRegionGraph() {
for (int i = 1; i <= n; i++) {
pivot = i;
sort(g[i].begin(), g[i].end(), Compare);
usedEdge[i].resize(g[i].size(), false);
for (int j = 0; j < g[i].size(); j++)
edgeIndex[i][g[i][j].first] = j;
}
for (int i = 1; i <= n; i++)
for (int j = 0; j < g[i].size(); j++)
if (!usedEdge[i][j]) {
regions++;
int node = i, edge = j;
do {
usedEdge[node][edge] = true;
int nextNode = g[node][edge].first;
int nextEdge = g[node][edge].second;
if (region[nextEdge].first == 0) {
region[nextEdge].first = regions;
orientation[nextEdge] = make_pair(node, nextNode);
}
else
region[nextEdge].second = regions;
edge = edgeIndex[nextNode][node] + 1;
if (edge == g[nextNode].size())
edge = 0;
node = nextNode;
} while (node != i);
}
for (int i = 1; i <= m; i++) {
graph[region[i].first].push_back(region[i].second);
graph[region[i].second].push_back(region[i].first);
}
}
void ColorRegionGraph() {
for (int i = 1; i <= regions; i++) {
degree[i] = graph[i].size();
Set.insert(make_pair(graph[i].size(), i));
}
while (!Set.empty()) {
pair<int, int> current = *Set.begin();
int node = current.second;
Set.erase(current);
if (seen[node])
continue;
seen[node] = true;
order.push_back(node);
for (auto &nextNode : graph[node])
if (!seen[nextNode]) {
Set.erase(make_pair(degree[nextNode], nextNode));
degree[nextNode]--;
Set.insert(make_pair(degree[nextNode], nextNode));
}
}
for (int i = regions - 1; i >= 0; i--) {
int node = order[i];
for (int j = 1; j <= 6; j++)
usedColor[j] = false;
for (auto &neighbour : graph[node])
usedColor[color[neighbour]] = true;
int j = 1;
while (usedColor[j])
j++;
color[node] = j;
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> X[i] >> Y[i];
for (int i = 1; i <= m; i++) {
int a, b;
cin >> a >> b;
g[a].push_back(make_pair(b, i));
g[b].push_back(make_pair(a, i));
}
ComputeRegionGraph();
ColorRegionGraph();
for (int i = 1; i <= m; i++) {
int a = orientation[i].first, b = orientation[i].second, flow = color[region[i].first] - color[region[i].second];
if (flow > 0)
cout << a << " " << b << " " << flow << "\n";
else
cout << b << " " << a << " " << -flow << "\n";
}
return 0;
}