Pagini recente » Cod sursa (job #3161777) | Cod sursa (job #1096608) | Cod sursa (job #2686378) | Cod sursa (job #2815775) | Cod sursa (job #1928911)
// la un cod corect
// libraria citirii si afisarii cu scanf si printf
// multa sanatate!
#include <cstdio>
// sefu la atan2, ne traiasca!
#include <cmath>
// baiatu cu sort
#include <algorithm>
// pt mapuri
#include <utility>
// pt graf
#include <map>
// marimea pateului
#define MAXN 100000
#define MAXK 200009
#define MAXM 600099
// structura mea favorita, mycreation
struct myc{
int x, y;
myc(int _x, int _y){
x=_x;
y=_y;
}
};
//aicisa niste declarari
int sef;
std::vector <bool> viz[MAXN+1];
std::vector <myc> g[MAXN+1];
std::map <int, int> mp[MAXN+1];
double x[MAXN+1], y[MAXN+1];
int a[MAXM], b[MAXM], moaca[MAXM];
bool done[MAXK+1], ok[7];
int q[MAXK+1], unde[MAXK+1], gr[MAXK+1];
char cul[MAXK+1];
std::vector <int> v[MAXK+1];
// asa se sorteaza niste muchii
bool cmp(const myc &a, const myc &b){
return atan2(y[a.x]-y[sef], x[a.x]-x[sef])<atan2(y[b.x]-y[sef], x[b.x]-y[sef]);
}
//profund...
int main(){
FILE *fin, *fout;
fin=fopen("nowherezero.in", "r");
fout=fopen("nowherezero.out", "w");
// ideea la problema asta e sa gasesti o 6-colorare a grafului fetelor
// fiecare fata va creste fluxul de pe o muchie in sensul ei trigonometric
// astfel fiecare muchie, in orice sens al ei, va avea costul intre -5 si 5
// partea naspa e determinarea grafului fetelor
// mai intai citim datele de intrare
int n, m;
fscanf(fin, "%d%d", &n, &m);
for(int i=1; i<=n; i++)
fscanf(fin, "%lf%lf", &x[i], &y[i]);
for(int i=0; i<2*m; i+=2){
fscanf(fin, "%d%d", &a[i], &b[i]);
a[i+1]=b[i];
b[i+1]=a[i];
g[a[i]].push_back(myc(b[i], i));
g[b[i]].push_back(myc(a[i], i+1));
}
// acum ar fi util ca in fiecare nod sa
// ii tinem vecinii sortati dupa unghi
for(int i=1; i<=n; i++){
sef=i;
std::sort(g[i].begin(), g[i].end(), cmp);
// tinem un vector de vizitari ale muchiilor
for(int j=0; j<(int)g[i].size(); j++)
viz[i].push_back(0);
// ne-ar ajuta sa stim si pozitiile nodurilor
// folosim un std::map
for(int j=0; j<(int)g[i].size(); j++)
mp[i][g[i][j].x]=j;
}
// pana epuizam toate muchiile din graf, construim noi fet(z)e, numerotate cu k
int k=0;
for(int i=1; i<=n; i++){
for(int j=0; j<(int)g[i].size(); j++) if(viz[i][j]==0){
//ne alegem muchia
int x=i;
myc y=g[i][j];
// si parcurgem noua fata determinata de muchia aleasa
k++;
while(y.x!=i){
// notam fata actuala pe muchia pe care suntem
moaca[y.y]=k;
// marcam muchia ca vizitata
viz[x][y.y]=1;
// si inaintam in graf, alegand prima mukie in sens trigonometric care urmeaza
int aux=x;
x=y.x;
int poz=mp[x][aux]-1;
if(poz==-1)
poz=g[x].size()-1;
y=g[x][poz];
}
moaca[y.y]=k;
viz[x][y.y]=1;
}
}
// e timpul sa ducem muchii prin graful feteor!
for(int i=0; i<2*m; i+=2){
v[moaca[i]].push_back(moaca[i+1]);
v[moaca[i+1]].push_back(moaca[i]);
}
// si sa il coloram in 6 culori!
// vom tine in permantenta o coada cu nodurile de grad <= 5
int st=0, dr=0;
for(int i=1; i<=k; i++){
gr[i]=v[i].size();
if(gr[i]<=5){
unde[i]=dr;
q[dr++]=i;
done[i]=1;
}
}
// parcurgem coada si o extindem pe parcurs
while(st<dr){
for(auto x:v[q[st]]){
if(done[x]==0){
gr[x]--;
if(gr[x]==5){
// inseram nodul la finalul cozii
unde[x]=dr;
q[dr++]=x;
done[x]=1;
}
}
}
st++;
}
//parcurgem de la dreapta la stanga coada si calculam culoarea fiecarui nod
for(int i=k-1; i>=0; i--){
// calculam culoarea nodului q[i]
for(int j=1; j<=6; j++)
ok[j]=1;
for(auto x:v[q[i]]){
if(unde[x]>unde[q[i]]){
// culoarea nodului x o influenteaza pe a mea
// nelasandu-ma sa o fixez egala cu cul[x]
ok[(int)cul[x]]=0;
}
}
// fiind maksim 5 culori interzise, macar una va fi disponibila pentru nodul CURent
for(int j=1; j<=6; j++)
if(ok[j])
cul[q[i]]=j;
}
// avand calculate culorile fetelor, nu mai trebuie decat sa afisam raspunsul
for(int i=0; i<2*m; i+=2){
int sol;
if(cul[moaca[i]]>cul[moaca[i+1]])
sol=i;
else sol=i+1;
int ans=cul[moaca[sol]]-cul[moaca[sol^1]];
fprintf(fout, "%d %d %d\n", a[sol], b[sol], ans);
}
// vedem la debug ce-a iesit
fclose(fin);
fclose(fout);
return 0;
}