Nu aveti permisiuni pentru a descarca fisierul grader_test8.in
Cod sursa(job #1024973)
Utilizator | Data | 9 noiembrie 2013 13:04:44 | |
---|---|---|---|
Problema | Nowhere-zero | Scor | 70 |
Compilator | cpp | Status | done |
Runda | Arhiva de probleme | Marime | 4.62 kb |
#include <fstream>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
ifstream F("nowhere-zero.in");
ofstream G("nowhere-zero.out");
/**
Construiesc regiunile si trag muchie intre pentru laturile comune din regiuni diferite.
Muchiile initiale le orientez. Intai fac un vector nxt care as ma trimita la urmatorul
punct. Cand ajung in acelasi punct am epuziat o regiune.
Colorez graful regiunilor si apoi contruiesc reteaua de circulatie. Colorarea se face cu
6 culori , deci pornesc de la graf minim si elimin din graf.
Complexitatea: O(N log N)
*/
const int Nmax = 200010;
const int debuging = 0;
#define IT(type) vector<type>::iterator
#define parc(type,it,vect) for (vector< type >::iterator it=vect.begin();it!=vect.end();++it)
#define x first
#define y second
int N,M,K;
pair<double,double> point[Nmax];
pair<int,int> edges[Nmax<<1];
vector<int> V[Nmax];
vector< vector<int> > regions;
int r_index[Nmax<<1];
vector< vector<int> > graph;
int nxt[Nmax<<1];
double angle[Nmax<<1];
int reverse_index(int x)
{
if ( x > M )
return x-M;
return x+M;
}
void print_vector(vector<int> A)
{
if ( !debuging ) return;
G<<"debug: ";
for (size_t i=0;i<A.size();++i)
G<<A[i]<<' ';
G<<'\n';
}
void read_data()
{
F>>N>>M;
for (int i=1;i<=N;++i)
F>>point[i].x>>point[i].y;
for (int i=1,x,y;i<=M;++i)
{
F>>x>>y;
edges[i] = make_pair(x,y);
edges[reverse_index(i)] = make_pair(y,x);
V[x].push_back( i );
V[y].push_back( reverse_index(i) );
}
}
bool angle_cmp(int x,int y)
{
return angle[x] < angle[y];
}
void compute_nxt()
{
for (int i=1;i<=N;++i)
{
parc(int,e,V[i])
angle[*e] = atan2(point[edges[*e].y].y-point[i].y,point[edges[*e].y].x-point[i].x);
sort(V[i].begin(),V[i].end(),angle_cmp);
for (size_t j=0;j<V[i].size();++j)
nxt[reverse_index(V[i][j])] = V[i][(j+1)%(int(V[i].size()))];
}
}
bool used[Nmax<<1];
void build_regions()
{
for (int x=1;x<=N;++x)
parc(int,nowe,V[x])
{
int e = *nowe;
vector<int> region;
for (;used[e] == 0 && edges[e].y != x ; e = nxt[e])
{
region.push_back(e);
r_index[e] = int(regions.size());
used[e] = 1;
}
if ( !used[e] )
{
region.push_back(e);
r_index[e] = int(regions.size());
used[e] = 1;
}
print_vector( region );
if ( region.size() )
regions.push_back( region );
}
K = regions.size();
}
void place_edges()
{
graph.resize(K+5);
for (int i=1;i<=M;++i)
{
graph[ r_index[i] ].push_back( r_index[reverse_index(i)] );
graph[ r_index[reverse_index(i)] ].push_back( r_index[i] );
}
for (int i=0;i<K;++i)
{
sort(graph[i].begin(),graph[i].end());
graph[i].erase( unique(graph[i].begin(),graph[i].end()) , graph[i].end() );
print_vector(graph[i]);
}
}
const int Colors = 6;
queue<int> q;
int degree[Nmax];
vector<int> order;
int color[Nmax];
int mark[Nmax];
int get_color(int node)
{
int X[Colors+5];
memset(X,0,sizeof(X));
print_vector(graph[node]);
parc(int,it,graph[node])
X[color[*it]] = 1;
for (int i=1;i<=Colors;++i)
if ( X[i] == 0 )
return i;
return 0;
}
void color_graph()
{
for (int i=0;i<K;++i)
degree[i] = int(graph[i].size());
for (int i=0;i<K;++i)
if ( degree[i] < Colors )
{
mark[i] = 1;
q.push( i );
}
while ( q.size() )
{
int now = q.front();
order.push_back( now );
q.pop();
parc(int,it,graph[now])
{
--degree[*it];
if ( degree[*it] < Colors && mark[*it] == 0 )
{
mark[*it] = 1;
q.push(*it);
}
}
}
for (int i=int(order.size())-1;i>=0;--i)
color[ order[i] ] = get_color(order[i]);
}
void print_data()
{
for (int i=1;i<=(M<<1);++i)
{
int flow = color[ r_index[i] ] - color[ r_index[reverse_index(i)] ];
if ( flow < 0 ) continue;
G<<edges[i].x<<' '<<edges[i].y<<' '<<flow<<'\n';
}
}
int main()
{
read_data();
compute_nxt();
build_regions();
place_edges();
color_graph();
print_data();
}