Cod sursa(job #1047219)

Utilizator dariusdariusMarian Darius dariusdarius Data 4 decembrie 2013 01:12:13
Problema Nowhere-zero Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.73 kb
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<queue>
using namespace std;
struct Node
{
    double x,y;
} a[100005];
struct Edge
{
    int x,y;
} e[600005];
int n,m,refr;
class MyHash
{
    public: inline bool operator()(const pair<int,int> &a) const
    {
        return a.first+a.second;
    };
};
unordered_map< pair<int,int> , int, MyHash> PA,Edges;
class cmp
{
    public: inline bool operator()(const int &a,const int &b) const
    {
        return PA[make_pair(refr,a)]<PA[make_pair(refr,b)];
    }
};
struct Nod
{
    int u,deg;
    Nod() {}
    Nod(int uu,int ddeg) {u=uu;deg=ddeg;}
    inline bool operator<(const Nod &other) const
    {
        return deg<other.deg;
    }
};
multimap<int,int> S;
int faces,face[600005];
int color[200005];
unordered_set<int> F[200005];
map<int,int> G[100005];
int start,in_set[200005];
void make_face(int a,int f)
{
    while(1)
    {
        face[a]=f;
        G[e[a].x].erase(PA[make_pair(e[a].x,e[a].y)]);
        if(e[a].y==start)
            break;
        map<int,int>::iterator it=G[e[a].y].upper_bound(PA[make_pair(e[a].y,e[a].x)]);
        if(it==G[e[a].y].end())
            it=G[e[a].y].begin();
        a=Edges[make_pair(e[a].y,it->second)];
    }
}
int degree[200005];
int f[7];
int Color(int u)
{
    memset(f,0,sizeof(f));
    for(auto &v : F[u])
        f[color[v]]=1;
    for(int c=1;c<=5;c++)
        if(!f[c])
            return c;
    return 6;
}
bool viz[200005];
vector<int> order;
void colorare()
{
    queue<int> q;
    for(int i=1;i<=faces;i++)
        if(degree[i]<6)
        {
            q.push(i);
            viz[i]=true;
        }
    while(!q.empty())
    {
        order.push_back(q.front());
        for(auto &v: F[q.front()])
        {
            --degree[v];
            if(degree[v]<6 && !viz[v])
            {
                q.push(v);
                viz[v]=true;
            }
        }
        q.pop();
    }
    for(vector<int>::reverse_iterator it=order.rbegin();it!=order.rend();it++)
        color[*it]=Color(*it);
}
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",&a[i].x,&a[i].y);
    double aux;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&e[i].x,&e[i].y);
        e[2*m+1-i]=e[i];swap(e[2*m+1-i].x,e[2*m+1-i].y);
        aux=100000000.0*atan2(a[e[i].y].y-a[e[i].x].y,a[e[i].y].x-a[e[i].x].x);
        PA[make_pair(e[i].x,e[i].y)]=(int)aux;
        aux=100000000.0*atan2(a[e[i].x].y-a[e[i].y].y,a[e[i].x].x-a[e[i].y].x);
        PA[make_pair(e[i].y,e[i].x)]=(int)aux;
        G[e[i].x][PA[make_pair(e[i].x,e[i].y)]]=e[i].y;
        G[e[i].y][PA[make_pair(e[i].y,e[i].x)]]=e[i].x;
        Edges[make_pair(e[i].x,e[i].y)]=i;
        Edges[make_pair(e[i].y,e[i].x)]=2*m+1-i;
    }
    for(int i=1;i<=2*m;i++)
        if(!face[i])
        {
            start=e[i].x;
            make_face(i,++faces);
        }
    for(int i=1;i<=m;i++)
        if(face[i]!=face[2*m+1-i])
        {
            F[face[i]].insert(face[2*m+1-i]);
            F[face[2*m+1-i]].insert(face[i]);
        }
    for(int i=1;i<=faces;i++)
    {
        degree[i]=(int)F[i].size();
        S.insert(make_pair(degree[i],i));
        in_set[i]=1;
    }
    colorare();
    for(int i=1;i<=m;i++)
    {
        int cost=color[face[i]]-color[face[2*m+1-i]];
        if(cost<0)
            printf("%d %d %d\n",e[i].y,e[i].x,-cost);
        else
            printf("%d %d %d\n",e[i].x,e[i].y,cost);
    }
    return 0;
}