Pagini recente » Cod sursa (job #3241266) | Cod sursa (job #3286207) | Cod sursa (job #1207980) | Cod sursa (job #1723857) | Cod sursa (job #987338)
Cod sursa(job #987338)
#include <fstream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <cstring>
#include <cmath>
#define NM 100010
#define MM 400010
#define x first
#define y second
using namespace std;
ifstream f("nowhere-zero.in");
ofstream g("nowhere-zero.out");
typedef pair<int, int> PI;
typedef pair<double, double> PD;
int N, M;
vector<int> G[NM];
PD Points[NM], Center;
map<PI, int> WallCode, WallValue;
map<PI, bool> WallVisited;
int WallZones[MM];
int NoZones;
set<int> GZones[MM];
bool Exists[MM];
int Degree[MM], ZoneColor[MM];
bool CompareByTan (int a, int b)
{
return atan2(Points[a].y-Center.y, Points[a].x-Center.x) < atan2(Points[b].y-Center.y, Points[b].x-Center.x);
}
void Read ()
{
f >> N >> M;
for (int i=1; i<=N; i++)
f >> Points[i].x >> Points[i].y;
for (int i=1; i<=M; i++)
{
int a, b;
f >> a >> b;
G[a].push_back(b);
G[b].push_back(a);
WallCode[make_pair(a, b)]=M;
WallCode[make_pair(b, a)]=i+M;
}
f.close();
}
void SortG ()
{
for (int i=1; i<=N; i++)
{
Center=Points[i];
sort(G[i].begin(), G[i].end(), CompareByTan);
}
}
int SearchPosition (int center, int next)
{
int P=0, U=G[center].size()-1, M, ANS=-1;
int vec;
double tan = atan2(Points[next].y-Points[center].y, Points[next].x-Points[center].x);
while (P<=U)
{
M=(P+U)/2;
vec=G[center][M];
if (atan2(Points[vec].y-Points[center].y, Points[vec].x-Points[center].y) <= vec)
{
ANS=M;
P=M+1;
}
else
U=M-1;
}
return ANS;
}
bool GoOnWalls (int source, int father, int node)
{
if (node==source)
{
++NoZones;
return 1;
}
int position=SearchPosition(node, father);
bool found = 0;
int j, size=G[node].size();
for (j=(position+1)%size; j!=father; j=(j+1)%size)
if (!WallVisited[make_pair(node, j)])
{
found=1;
break;
}
if (found==0) return 0;
WallVisited[make_pair(node, j)]=1;
found = GoOnWalls(source, node, j);
if (found==1)
{
WallZones[WallCode[make_pair(node, j)]]=NoZones;
return 1;
}
WallVisited[make_pair(node, j)]=0;
return 0;
}
void BuildZones ()
{
int i;
vector<int>::iterator it;
for (i=1; i<=N; i++)
for (it=G[i].begin(); it!=G[i].end(); ++it)
if (!WallVisited[make_pair(i, *it)])
{
WallVisited[make_pair(i, *it)]=1;
bool ok=GoOnWalls(i, i, *it);
int code=WallCode[make_pair(i, *it)];
if (ok)
WallZones[code]=NoZones;
else
WallVisited[make_pair(i, *it)]=0;
}
}
void BuildGraph ()
{
int i;
vector<int>::iterator it;
for (i=1; i<=N; i++)
for (it=G[i].begin(); it!=G[i].end(); ++it)
if (i<*it)
{
int zone1 = WallZones[WallCode[make_pair(i, *it)]];
int zone2 = WallZones[WallCode[make_pair(*it, i)]];
if (zone1!=0 && zone2!=0)
{
GZones[zone1].insert(zone2);
GZones[zone2].insert(zone1);
}
}
}
void ColorZones ()
{
stack<int> MyStack;
set<PI> MySet;
set<PI>::iterator set1, set2;
set<int>::iterator it;
for (int i=1; i<=NoZones; i++)
{
Exists[i]=1;
Degree[i]=GZones[i].size();
MySet.insert(make_pair(Degree[i], i));
}
while (!MySet.empty())
{
set1=MySet.begin();
int node = set1->second;
MySet.erase(set1);
if (Exists[node]==0) continue;
MyStack.push(node);
Exists[node]=0;
for (it=GZones[node].begin(); it!=GZones[node].end(); ++it)
if (Exists[*it])
{
set1=MySet.find(make_pair(Degree[*it], *it));
if (set1==MySet.end()) continue;
MySet.erase(set1);
Degree[*it]--;
MySet.insert(make_pair(Degree[*it], *it));
}
}
bool Marked[7];
while (!MyStack.empty())
{
int node = MyStack.top();
MyStack.pop();
for (int i=0; i<=6; i++)
Marked[i]=0;
for (it=GZones[node].begin(); it!=GZones[node].end(); ++it)
Marked[ZoneColor[*it]]=1;
for (int i=1; i<=6; i++)
if (Marked[i]==0)
{
ZoneColor[node]=i;
break;
}
}
}
void Print ()
{
int i;
vector<int>::iterator it;
for (i=1; i<=N; i++)
for (it=G[i].begin(); it!=G[i].end(); ++it)
if (i<*it)
{
int zone1 = WallZones[WallCode[make_pair(i, *it)]];
int zone2 = WallZones[WallCode[make_pair(*it, i)]];
if (ZoneColor[zone1]>ZoneColor[zone2])
g << i << ' ' << (*it) << ' ' << (ZoneColor[zone1] - ZoneColor[zone2]) << '\n';
else
g << (*it) << ' ' << i << ' ' << (ZoneColor[zone2] - ZoneColor[zone1]) << '\n';
}
g.close();
}
int main ()
{
Read();
SortG();
BuildZones();
BuildGraph();
ColorZones();
Print();
return 0;
}