Pagini recente » Cod sursa (job #1479501) | Cod sursa (job #516296) | Cod sursa (job #857499) | Cod sursa (job #2100887) | Cod sursa (job #1098111)
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#define pii pair<int, int>
using namespace std;
int n, m, P0, nreg, grad[300100], color[300100];
pii regiune[300100], M[300100];
double X[100100], Y[100100];
vector <pii> G[100100];
vector <int> GReg[300100], coloringorder;
vector <bool> viz[100100];
map <int, int> IndexMuchie[100100];
set <pii> Q;
bool sters[300100], uz[7];
inline void Citire()
{
int i, x, y;
ifstream fin("nowhere-zero.in");
fin >> n >> m;
for(i = 1; i <= n; ++i)
fin >> X[i] >> Y[i];
for(i = 1; i <= m; ++i)
{
fin >> x >> y;
G[x].push_back(make_pair(y, i));
G[y].push_back(make_pair(x, i));
}
fin.close();
}
inline bool Sortare(pii a, pii b)
{
return atan2(Y[a.first] - Y[P0], X[a.first] - X[P0]) < atan2(Y[b.first] - Y[P0], X[b.first] - X[P0]);
}
inline void BuildRegionGraph()
{
int i, j, A, B, nod, poz, nextnod, muchie;
for(i = 1; i <= n; ++i)
{
// sortez vecinii punctului in jurul lui
P0 = i;
sort(G[i].begin(), G[i].end(), Sortare);
grad[i] = G[i].size();
viz[i].reserve(grad[i]);
for(j = 0; j < grad[i]; ++j)
IndexMuchie[i][G[i][j].first] = j;
}
for(i = 1; i <= n; ++i)
{
for(j = 0; j < grad[i]; ++j)
{
if(!viz[i][j])
{
nreg++; // am o regiune noua
nod = i;
poz = j;
do // construiesc regiunea, parcurgand muchiile ce o inconjoara
{
viz[nod][poz] = true;
nextnod = G[nod][poz].first;
muchie = G[nod][poz].second;
if(regiune[muchie].first == 0)
{
regiune[muchie].first = nreg;
M[muchie] = make_pair(nod, nextnod);
}
else
regiune[muchie].second = nreg;
poz = IndexMuchie[nextnod][nod] + 1;
if(poz == grad[nextnod])
poz = 0;
nod = nextnod;
}
while(nod != i);
}
}
}
// construiesc graful regiunilor
for(i = 1; i <= m; ++i)
{
A = regiune[i].first;
B = regiune[i].second;
// regiunile A, B se ating in muchia i
GReg[A].push_back(B);
GReg[B].push_back(A);
}
}
inline void ColoreazaGrafRegiuni()
{
vector <int>::iterator it;
pii now;
int i, x, c;
for(i = 1; i <= nreg; ++i)
{
grad[i] = GReg[i].size();
Q.insert(make_pair(grad[i], i));
}
while(!Q.empty())
{
now = *Q.begin();
Q.erase(now);
x = now.second;
if(sters[x])
continue;
sters[x] = true;
coloringorder.push_back(x);
for(it = GReg[x].begin(); it != GReg[x].end(); ++it)
{
if(!sters[*it])
{
Q.erase(make_pair(grad[*it], *it));
grad[*it]--;
Q.insert(make_pair(grad[*it], *it));
}
}
}
for(i = nreg - 1; i >= 0; --i)
{
x = coloringorder[i];
for(c = 1; c <= 6; ++c)
uz[c] = false;
for(it = GReg[x].begin(); it != GReg[x].end(); ++it)
uz[color[*it]] = true;
c = 1;
while(uz[c])
c++;
color[x] = c;
}
}
inline void Afisare()
{
int i, x, y, capacitate;
ofstream fout("nowhere-zero.out");
for(i = 1; i <= m; ++i)
{
x = M[i].first;
y = M[i].second;
capacitate = color[regiune[i].first] - color[regiune[i].second];
if(capacitate > 0)
fout << x << ' ' << y << ' ' << capacitate << "\n";
else
fout << y << ' ' << x << ' ' << (-capacitate) << "\n";
}
fout.close();
}
int main()
{
Citire();
BuildRegionGraph();
ColoreazaGrafRegiuni();
Afisare();
return 0;
}