#include # define endl '\n' # define clr(x,a) memset(x,a,sizeof(x)) # define vi vector # define all(a) a.begin(), a.end() # define deb(x) cout<<#x<<"=="< mapa; //12+23-13 clock_t vreme0; struct slog_quea{ float val; int idstaz, j, id; bool operator <(const slog_quea &P)const{ return P.val>val; } }qupom; struct Solution{ int id, x, y; }res[mxN]; struct Runner{ float s, ss; int id, x, y; // int poredak; }r[mxN], r2[mxN]; struct Point{ int x, y, id, idrunera; }bc[mxN]; struct pagru{ vi v; //idevi tacaka koje sam obisao float duzina; int idrunnera, pocx, pocy; }staze[mxN]; struct Dinamika{ int prev, iksd, t, sta_je_izmedju; //izkogsamdosa float score; void ispis(int x){ cout<<"za: "< "; cout<<"score=="<b.s;} bool cmp_r_rastuce(Runner a, Runner b){return a.sb.duzina;} bool cmp_staze_rastuce(pagru a, pagru b){return a.duzinay;} bool cmp_float_rastuce(float x, float y) {return x q; void svi1(){ for(int i=1; i<=k; i++){ r[i].x=bc[i].x; r[i].y=bc[i].y; bc[i].idrunera=i; } for(int i=k+1; i<=n; i++) bc[i].idrunera=1; } float dist(ll x1, ll y1, ll x2, ll y2){ ll ry=(y1-y2), rx=(x1-x2); return sqrt(rx*rx+ry*ry); } void swapuj_x_y(){ for(int i=1; i<=n; i++) swap(bc[i].x, bc[i].y); } void calcscore(){ ///ovo sranje menjaa r-oveeeeeeeee !!!!!!!! fadsds gdf f score=0; sort(r+1, r+1+k, cmp_r_id); for(int i=1; i<=k; i++){ r[i].x=res[i].x; r[i].y=res[i].y; } sort(bc+1, bc+1+n, cmp_bc_id); for(int i=1; i<=n; i++){ score+=dist(r[bc[i].idrunera].x, r[bc[i].idrunera].y, bc[i].x, bc[i].y)*r[bc[i].idrunera].s; r[bc[i].idrunera].x=bc[i].x; r[bc[i].idrunera].y=bc[i].y; } } void unos(){ if(tin==1) freopen("input_t1.in", "r", stdin); else if(tin==2) freopen("input_t2.in", "r", stdin); else if(tin==3) freopen("input_t3.in", "r", stdin); else if(tin==4) freopen("input_t4.in", "r", stdin); else if(tin==5) freopen("input_t5.in", "r", stdin); else if(tin==6) freopen("testic.in", "r", stdin); else freopen("runners.in", "r", stdin); sc("%d%d", &n, &k); if(k<=10) test=1; else if(k<=100) test=2; else if(k<=1000) test=3; else if(k<=10000) test=4; else test=5; for(int i=1; i<=k; i++){ sc("%f", &r[i].s); r[i].id=i; r[i].ss=r[i].s*r[i].s; r[i].x=r[i].y=1; res[i].id=i; res[i].x=res[i].y=1; } h1=w1=1e9; h2=w2=0; for(int i=1; i<=n; i++){ sc("%d %d", &bc[i].x, &bc[i].y); bc[i].id=i; bc[i].idrunera=1; h1=min(h1, bc[i].y); h2=max(h2, bc[i].y); w1=min(w1, bc[i].x); w2=max(w2, bc[i].x); } // swapuj_x_y(); // for(int i=1; i<=n; i++){ // // } dw=w2-w1+1; dh=h2-h1+1; } void ispis(){ sort(res+1, res+1+k, cmp_res_id); sort(bc+1, bc+1+n, cmp_bc_id); freopen("runners.out", "w", stdout); for(int i=1; i<=k; i++) pr("%d %d\n", res[i].x, res[i].y); for(int i=1; i<=n; i++){ pr("%d\n", bc[i].idrunera); } // calcscore(); // deb(score) } void ispisi_staze(){ cout<<"staze\n"; for(int i=1; i<=k; i++){ cout< "; for(int j: staze[i].v) cout<1){ ret++; x/=10; } return ret; } void calc_opt_score(){ //racuna_opt_score O(k), radi sa duzine[] opt_score=0; for(int i=1; i<=k; i++) opt_score+=r[i].s*duzine[i]; } void update_s1(int p1, int p2, int p3){ //racuna d1 O(sqrt) if(p1==-1){ if(p3==-1) d1=0; else d1=-dist(bc[p2].x, bc[p2].y, bc[p3].x, bc[p3].y); } else{ if(p3==-1) d1=-dist(bc[p2].x, bc[p2].y, bc[p1].x, bc[p1].y); else d1=dist(bc[p1].x, bc[p1].y, bc[p3].x, bc[p3].y) //dist1 -dist(bc[p2].x, bc[p2].y, bc[p1].x, bc[p1].y) //dist2 -dist(bc[p2].x, bc[p2].y, bc[p3].x, bc[p3].y); //dist3 } } void update_s2(int pret, int p, int s2){ //racuna d2 O(sqrt) -- N al se to neutralise //ne radi za sada (treba ubaciti prethodni) int sajz2=staze[s2].v.size(); // cout<<"updatujem s2\n"; if(idv==sajz2){ //pucam ga na kraj if(pret==-1) d2=dist(bc[staze[s2].v[sajz2-1]].x, bc[staze[s2].v[sajz2-1]].y, bc[p].x, bc[p].y); else d2=dist(bc[pret].x, bc[pret].y, bc[p].x, bc[p].y); return; } while(staze[s2].v[idv]=(maxtw) || th>=(maxth)) continue; if(indeks_grupe[idx]==2) continue; br++; indeks_grupe[br]=1; r[br].x=bc[i].x; r[br].y=bc[i].y; staze[br].v.clear(); staze[br].v.pb(i); staze[br].duzina=0; if(br==k) break; } // deb(br); // deb(k); // exit(k-br); // for(int i=1; i<=n; i++){ // if(indeks_grupe[i]) continue; // if(br==k) return; // br++; // indeks_grupe[i]=1; // // r[i].x=bc[i].x; // r[i].y=bc[i].y; // // staze[i].v.clear(); // staze[i].v.pb(i); // staze[i].duzina=0; // } } void algoritam_najblizi_put_bez_staza_samo_najblizi(){ // cout<<"najblizi put_bez_staza_samo_najblizi\n"; poredjaj_redom(); // poredjaj_kakasto(); float najblizi, tren; ll najbl_ll; int t1[2], t2[2], mojid; for(int i=k+1; i<=n; i++){ if(indeks_grupe[i]) continue; najblizi=100.0*maxd_squared; t1[0]=bc[i].x; t1[1]=bc[i].y; for(int j=1; j<=k; j++){ if(staze[j].v.size()==0) continue; // if(staze[j].v[staze[j].v.size()-1]>i) continue; t2[0]=r[j].x; t2[1]=r[j].y; tren=r[j].ss*dist_squared(t1, t2); if(tren0){ if(clock()-vreme0>2500) break; brstek2=0; for(int i=1; i<=brstek; i++){ br_optimizacija=0; optimizacija(stek[i], k); if(br_optimizacija){ brstek2++; stek2[brstek2]=stek[i]; } } for(int i=1; i<=brstek2; i++) stek[i]=stek2[i]; brstek=brstek2; } } for(int i=1; i<=k/2; i++) optimizacija(i, k-i+1); konacna_raspodela(); } void pocetak_staza(){ for(int i=1; i<=k; i++){ staze[i].pocx=res[i].x; staze[i].pocy=res[i].y; staze[i].duzina=0; staze[i].v.clear(); staze[i].v.pb(i); } } void algoritam_najblizi_put(){ // cout<<"algoritam najblizi put\n"; pocetak_staza(); ll najblizi, tren; int t1[2], t2[2], mojid, pret; for(int i=k+1; i<=n; i++){ najblizi=maxd_squared; t1[0]=bc[i].x; t1[1]=bc[i].y; for(int j=1; j<=min(k, 1000); j++){ pret=staze[j].v[staze[j].v.size()-1]; t2[0]=bc[pret].x; t2[1]=bc[pret].y; tren=dist_squared(t1, t2); if(trenmaxval){ maxval=trenval; ret=j; } } if(ret!=-1) update_duzine(i, ret); return ret; } void update_queue(int idstaz){ qupom.idstaz=idstaz; pzsq[idstaz]++; // if(pzsq[idstaz]==2) cout<<"yewtew\n"; for(int j=0; j=2) update_queue(i); } prazni=br_viska=0; for(int i=1; i<=k; i++) if(staze[i].v.size()==0) prazni++; // int raz=0; // while(q.size()){ // if(q.top().j>=staze[q.top().idstaz].v.size()) raz++; //// pr("%d\n", q.top().id); // q.pop(); // } // deb(raz); // exit(100); while(prazni>0 && q.size()){ qupom=q.top(); q.pop(); if(pzsq[qupom.idstaz]!=qupom.id) continue; prazni--; ideovi_viskova[++br_viska]=staze[qupom.idstaz].v[qupom.j]; staze[qupom.idstaz].v.erase(staze[qupom.idstaz].v.begin()+qupom.j); staze[qupom.idstaz].duzina-=qupom.val; if(staze[qupom.idstaz].v.size()>=2) update_queue(qupom.idstaz); else pzsq[qupom.idstaz]++; } deb(br_viska); deb(prazni); } void delovi_koordinatnog_sistema(){ //dusko me izjebo if(dw1) granica++; res[r[nviska].id].x=bc[staze[i].v[0]].x; res[r[nviska].id].y=bc[staze[i].v[0]].y; for(int j: staze[i].v) bc[j].idrunera=r[nviska].id; nviska++; } } for(int i=nviska, j=1; j<=br_viska; i++, j++){ res[r[i].id].x=bc[ideovi_viskova[j]].x; res[r[i].id].y=bc[ideovi_viskova[j]].y; bc[ideovi_viskova[j]].idrunera=r[i].id; } } void rekurzivno(int poc, int kraj, int dub, int id_gr){ //[poc, kraj] if(dub&1) sort(bc+poc, bc+1+kraj, cmp_bc_x); //x else sort(bc+poc, bc+1+kraj, cmp_bc_y); //y if(dub==max_dub){ //sklapanje for(int i=poc; i<=kraj; i++) indeks_grupe[bc[i].id]=id_gr; return; } rekurzivno(poc, (poc+kraj)/2, dub+1, id_gr); rekurzivno( (poc+kraj)/2+1, kraj, dub+1, id_gr+(1<<(max_dub-dub-1)) ); } void izracunaj_cnt_grupice(){ int delovi=(1<<(max_dub-1)); for(int i=0; i uzeo sam je "; idr++; br_gr[id_gr]++; uradjen[i]=idr; // deb(idr); r[idr].x=bc[i].x; r[idr].y=bc[i].y; staze[idr].pocx=r[idr].x; staze[idr].pocy=r[idr].y; staze[idr].duzina=0; staze[idr].v.clear(); staze[idr].v.pb(i); grupe_runnera[id_gr][br_gr[id_gr]]=idr; } } void trazenje_najbrzeg_runera(){ float najblizi, tren; // for(int i=0; i<8; i++){ // cout<<"grupa "<=1){ idr=staze[mojid].v[staze[mojid].v.size()-1]; staze[mojid].duzina+=dist(bc[i].x, bc[i].y, bc[idr].x, bc[idr].y); } staze[mojid].v.pb(i); r[mojid].x=bc[i].x; r[mojid].y=bc[i].y; } // int smica=0; // for(int i=1; i<=k; i++){ // cout<<"staza: "<1){ sled=dp[tren][pos].iksd; sledtren=dp[tren][pos].t; zapostaviti=dp[tren][pos].sta_je_izmedju; if(tren!=sledtren){ bc[pos].idrunera=zapostaviti; if(zapostaviti==1) bc[sled].idrunera=2; else bc[sled].idrunera=1; } else{ if(zapostaviti==2) bc[sled].idrunera=bc[pos].idrunera=1; else bc[sled].idrunera=bc[pos].idrunera=2; } for(int j=sled+1; j<=pos-1; j++) bc[j].idrunera=zapostaviti; // bc[sled].idrunera=bc[pos].idrunera=tren; pos=sled; tren=sledtren; } } void postavi(bool t, int a, int b){ //a->b a>=b float d_ij_i=dist(bc[a].x, bc[a].y, bc[b].x, bc[b].y); if(a==b) d_ij_i=0; trenic.iksd=b; trenic.sta_je_izmedju=suprotran(t); trenic.t=t; trenic.score=dp[t][b].score+d_ij_i*s[t]; if(b+1==a) trenic.prev=dp[t][b].prev; else{ trenic.prev=a-1; if(dp[t][b].prev!=0) trenic.score+=dist(bc[dp[t][b].prev].x, bc[dp[t][b].prev].y, bc[b+1].x, bc[b+1].y)*s[(!t)]; trenic.score+=pd[max(a-b-2, 1)]*s[(!t)]; } if(trenic.score60000) delovi_koordinatnog_sistema(); else{ podela_na_max_dub(); //slicno je kao delovi kod sis al je bolje (nadam se) } } ispis(); return 0; }