Cod sursa(job #3313516)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 4 octombrie 2025 21:57:09
Problema Nowhere-zero Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
// Ilie "The-Winner" Dumitru
// Dumnezeu sa o ierte
#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define err(...) fprintf(stderr, __VA_ARGS__)
using ll=long long;
constexpr int NMAX=100'005;
constexpr ll MOD=1'000'000'007;

struct pct
{
	double x, y;

	bool operator<(pct o) const
	{
		if(x!=o.x)
			return x<o.x;
		return y<o.y;
	}

	bool left() const
	{
		pct p={0, 0};
		return p<*this;
	}

	pct operator-(pct o) const
	{
		return {x-o.x, y-o.y};
	}
};

int N, M;
pct v[NMAX];

struct seg
{
	int u, v, i;

	bool operator<(seg o) const
	{
		if(::v[u].x!=::v[o.u].x)
			return ::v[u].x<::v[o.u].x;
		if(::v[u].y!=::v[o.u].y)
			return ::v[u].y<::v[o.u].y;
		pct p=::v[v]-::v[u];
		pct q=::v[o.v]-::v[o.u];
		if(p.left()!=q.left())
			return p.left()<q.left();
		return p.x*q.y-q.x*p.y>0;
	}
};

int M2;
std::vector<seg> E;
std::vector<int> nxt;
std::vector<int> face;
int F;
std::vector<std::set<int> > G;
std::vector<int> deg;
std::vector<int> col;
std::vector<int> init_u, init_v;

int main()
{
	FILE* f=fopen("nowhere-zero.in", "r"), *g=fopen("nowhere-zero.out", "w");
	int i, j, x, y;

	fscanf(f, "%d%d", &N, &M);
	M2=M*2;
	E.resize(M2);
	nxt.resize(M2);
	face.resize(M2);
	init_u.resize(M2);
	init_v.resize(M2);
	for(i=0;i<N;++i)
		fscanf(f, "%lf%lf", &v[i].x, &v[i].y);
	for(i=0;i<M;++i)
	{
		fscanf(f, "%d%d", &x, &y);
		init_u[i]=x--;
		init_v[i]=y--;
		E[i*2].u=x;
		E[i*2].v=y;
		E[i*2].i=i*2;
		E[i*2+1].v=x;
		E[i*2+1].u=y;
		E[i*2+1].i=i*2+1;
	}

	std::sort(all(E));

	for(i=0;i<M*2;++i)
	{
		for(j=i+1;j<M*2 && E[i].u==E[j].u;++j);
		nxt[E[j-1].i^1]=E[i].i;
		for(--j;i<j;++i)
			nxt[E[i].i^1]=E[i+1].i;
	}

	for(i=0;i<M*2;++i)
		face[i]=-1;
	for(i=0;i<M*2;++i)
		if(face[i]==-1)
		{
			for(j=i;face[j]==-1;j=nxt[j])
				face[j]=F;
			++F;
		}

	G.resize(F);
	deg.resize(F);
	col.resize(F);
	for(i=0;i<M;++i)
		if(face[i*2]!=face[i*2+1])
		{
			G[face[i*2]].insert(face[i*2+1]);
			G[face[i*2+1]].insert(face[i*2]);
		}

	std::stack<int> s, r;
	for(i=0;i<F;++i)
	{
		deg[i]=sz(G[i]);
		if(deg[i]<6)
			s.push(i);
	}

	while(!s.empty())
	{
		x=s.top();
		s.pop();
		r.push(x);

		for(int o : G[x])
			if(--deg[o]==5)
				s.push(o);
	}

	while(!r.empty())
	{
		x=r.top();
		r.pop();
		std::set<int> ngh;

		for(int o : G[x])
			ngh.insert(col[o]);
		for(i=1;i<6 && ngh.count(i);++i);
		col[x]=i;
	}

	for(i=0;i<M;++i)
	{
		if(col[face[i*2+1]]>col[face[i*2]])
			fprintf(g, "%d %d %d\n", init_u[i], init_v[i], col[face[i*2+1]]-col[face[i*2]]);
		else
			fprintf(g, "%d %d %d\n", init_v[i], init_u[i], col[face[i*2]]-col[face[i*2+1]]);
	}

	fclose(f);
	fclose(g);
	return 0;
}