Pagini recente » Organizatori preONI 2007 | Profil tabara | Infoarena Monthly 2014 - Premii | Cod sursa (job #412852) | Cod sursa (job #1245963)
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int Nr, n, m, st[600009], dr[600009], poligon[600009], nxt[600009], Ap[600009], culoare[600009], grad[600009];
double X[100009], Y[100009];
priority_queue < pair < int , int > > PQ;
vector < int > muchii[100009], v[600009], order;
vector < pair < double, int > > vec;
double Det_Unghi(double x, double y)
{
double result = (double)atan2 (y,x) * 180 / M_PI + 90;
if (result < 0) result = 360 + result;
return result;
}
int Get_color (int nod)
{
int mp = 0;
for (vector < int > :: iterator it = v[nod].begin(); it != v[nod].end(); it++)
if (Ap[*it]) mp |= 1<<culoare[*it];
for (int i=1; i<=7; i++)
if ( (mp & (1<<i)) == 0)
return i;
}
int rev (int i)
{
if (i<=m) return i+m;
return i-m;
}
int main()
{
freopen ("nowhere-zero.in", "r", stdin);
freopen ("nowhere-zero.out", "w", stdout);
scanf ("%d %d", &n, &m);
for (int i=1; i<=n; i++)
scanf ("%lf %lf", &X[i], &Y[i]);
for (int i=1; i<=m; i++)
{
scanf ("%d %d", &st[i], &dr[i]);
dr[i+m] = st[i];
st[i+m] = dr[i];
}
for (int i=1; i<=2*m; i++)
muchii[st[i]].push_back(i);
for (int i=1; i<=n; i++)
{
vec.clear();
for (vector < int > :: iterator it = muchii[i].begin(); it != muchii[i].end(); it++)
vec.push_back ( make_pair ( (double)Det_Unghi ( (double)X[dr[*it]] - X[i], (double)Y[dr[*it]] - Y[i] ) , *it) ) ;
sort (vec.begin(), vec.end());
for (int j = 0; j < vec.size(); j++)
nxt [rev(vec[j].second)] = vec[(j+1)%vec.size()].second;
}
for (int i=1; i<=2*m; i++)
if (poligon[i] == 0)
{
int j = i;
poligon[i] = ++Nr;
while (1)
{
j = nxt[j];
if (poligon[j] != 0) break;
poligon[j] = Nr;
}
}
for (int i=1; i<=m; i++)
if (poligon[i] != poligon[m+i])
{
v[poligon[i]].push_back(poligon[m+i]);
v[poligon[m+i]].push_back(poligon[i]);
grad[poligon[i]] ++;
grad[poligon[i+m]] ++;
}
for (int i=1; i<=Nr; i++)
PQ.push(make_pair(grad[i], i));
while (1)
{
pair < int , int > tp;
while (1)
{
if (PQ.empty()) break;
tp = PQ.top();
if (grad[tp.second] == tp.first && !Ap[tp.second]) break;
PQ.pop();
}
if (PQ.empty()) break;
PQ.pop();
order.push_back(tp.second);
Ap[tp.second] = 1;
for (vector < int > :: iterator it = v[tp.second].begin(); it != v[tp.second].end(); it++)
if (Ap[*it] == 0)
{
grad[*it] --;
PQ.push(make_pair(grad[*it], *it));
}
}
reverse(order.begin(), order.end());
for (int i=1; i<=Nr; i++)
Ap[i] = 0;
for (vector < int > :: iterator it = order.begin(); it != order.end(); it++)
{
Ap[*it] = 1;
culoare[*it] = Get_color(*it);
}
for (int i=1; i<=2*m; i++)
if (culoare[poligon[i]] < culoare[poligon[rev(i)]])
printf ("%d %d %d\n", st[i], dr[i], culoare[poligon[rev(i)]] - culoare[poligon[i]]);
return 0;
}