#include <cstdio> #include <algorithm> /* * Zadanie: ban * Autor rozwiązania: Jan Horodecki */ //#define DEBUG 1 //#ifdef DEBUG //#include <cassert> //void printState(); //#endif #define ui unsigned int struct drogaT{ int s;//numer miasta poczatkowego (-1) int d;//numer miasta docelowego (-1) unsigned long long* c;//cena połączenia }; struct miastoT{ int ls;//liczba sąsiadów unsigned long long c;//cena bananow drogaT* d; }; bool cmp(const drogaT &a,const drogaT &b){ return a.s<b.s || ( a.s==b.s && a.d<b.d); } static unsigned int n,q; static drogaT* p; static miastoT* miasto; static unsigned long long* cennik; drogaT* znajdz_d(int s,int d){ drogaT* lista=miasto[s].d; int ls=miasto[s].ls; int sr,p=0,k=ls-1; while(p<k){ sr=(p+k)/2; if(lista[sr].d>=d)k=sr; else p=sr+1; } //fprintf(stderr,"Test"); if(lista[p].d==d)return lista+p; //fprintf(stderr,"Test1"); return NULL; } void solve_b(){ int curr=0;//Zaczynamy w mieście 1 (-1 = 0) int a,b; unsigned long long nc; long long* koszt=new long long[n]; int* kolejka=new int[n]; int pocz_kol,kon_kol,ls,maksind; long long maks,zysk; drogaT* lista; int c; //printState(); for(ui i=0;i<q;i++){ scanf("%d",&c); if(c==1){ scanf("%d%llu",&a,&nc); a--; miasto[a].c=nc; }else{ scanf("%d%d%llu",&a,&b,&nc); a--;b--; *(znajdz_d(a,b)->c)=nc; } for(ui j=0;j<n;j++){ koszt[j]=-1; } koszt[curr]=0; kolejka[0]=curr; pocz_kol=0;kon_kol=1; maks=-1000000000000000010LL; maksind=n+1; while(pocz_kol<kon_kol){ ls=miasto[kolejka[pocz_kol]].ls; lista=miasto[kolejka[pocz_kol]].d; for(int j=0;j<ls;j++){ if(koszt[lista[j].d]==-1){ koszt[lista[j].d]=koszt[kolejka[pocz_kol]]+*(lista[j].c); zysk=(long long)(miasto[lista[j].d].c)-koszt[lista[j].d]; if(zysk>maks){ maks=zysk; maksind=lista[j].d; }else if(zysk==maks && maksind>lista[j].d){ maksind=lista[j].d; } kolejka[kon_kol]=lista[j].d; kon_kol++; } } pocz_kol++; } printf("%d ",maksind+1); curr=maksind; } } #ifdef DEBUG void printState(){ for(ui i=0;i<n;i++){ fprintf(stderr,"Miasto %2u (banany: %3llu) (sasiezdzi: %2d):\n",i,miasto[i].c,miasto[i].ls); for(int j=0;j<miasto[i].ls;j++){ fprintf(stderr," (%2d) ===%-2llu==>%2d\n",miasto[i].d[j].s,*miasto[i].d[j].c,miasto[i].d[j].d); } } printf("______________________________________________________________\n"); } #endif int main(){ scanf("%d%d",&n,&q); p=new drogaT[2*(n-1)]; miasto=new miastoT[n]; cennik=new unsigned long long[n-1]; for(ui i=0;i<n;i++){ scanf("%llu",&miasto[i].c); miasto[i].ls=0; miasto[i].d=NULL; } for(ui i=0;i<n-1;i++){ scanf("%d%d%llu",&p[2*i].s,&p[2*i].d,&cennik[i]); p[2*i].s--; p[2*i].d--; p[2*i].c=&cennik[i]; p[2*i+1].s=p[2*i].d; p[2*i+1].d=p[2*i].s; p[2*i+1].c=p[2*i].c; } std::sort(p,p+2*(n-1),cmp); int curr=0; for(ui i=0;i<2*(n-1);i++){ if(p[i].s==curr){ miasto[curr].d=&p[i]; curr++; } //fprintf(stderr," %d %d %llu sorted?\n",p[i].s,p[i].d,*p[i].c); if( i+1<2*(n-1) && p[i+1].s==curr ){ miasto[curr-1].ls=int(&p[i+1]-miasto[curr-1].d); //fprintf(stderr," %d %d <<<\n",curr-1,miasto[curr-1].ls); } } miasto[curr-1].ls=int(p+2*(n-1)-miasto[curr-1].d); solve_b(); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | #include <cstdio> #include <algorithm> /* * Zadanie: ban * Autor rozwiązania: Jan Horodecki */ //#define DEBUG 1 //#ifdef DEBUG //#include <cassert> //void printState(); //#endif #define ui unsigned int struct drogaT{ int s;//numer miasta poczatkowego (-1) int d;//numer miasta docelowego (-1) unsigned long long* c;//cena połączenia }; struct miastoT{ int ls;//liczba sąsiadów unsigned long long c;//cena bananow drogaT* d; }; bool cmp(const drogaT &a,const drogaT &b){ return a.s<b.s || ( a.s==b.s && a.d<b.d); } static unsigned int n,q; static drogaT* p; static miastoT* miasto; static unsigned long long* cennik; drogaT* znajdz_d(int s,int d){ drogaT* lista=miasto[s].d; int ls=miasto[s].ls; int sr,p=0,k=ls-1; while(p<k){ sr=(p+k)/2; if(lista[sr].d>=d)k=sr; else p=sr+1; } //fprintf(stderr,"Test"); if(lista[p].d==d)return lista+p; //fprintf(stderr,"Test1"); return NULL; } void solve_b(){ int curr=0;//Zaczynamy w mieście 1 (-1 = 0) int a,b; unsigned long long nc; long long* koszt=new long long[n]; int* kolejka=new int[n]; int pocz_kol,kon_kol,ls,maksind; long long maks,zysk; drogaT* lista; int c; //printState(); for(ui i=0;i<q;i++){ scanf("%d",&c); if(c==1){ scanf("%d%llu",&a,&nc); a--; miasto[a].c=nc; }else{ scanf("%d%d%llu",&a,&b,&nc); a--;b--; *(znajdz_d(a,b)->c)=nc; } for(ui j=0;j<n;j++){ koszt[j]=-1; } koszt[curr]=0; kolejka[0]=curr; pocz_kol=0;kon_kol=1; maks=-1000000000000000010LL; maksind=n+1; while(pocz_kol<kon_kol){ ls=miasto[kolejka[pocz_kol]].ls; lista=miasto[kolejka[pocz_kol]].d; for(int j=0;j<ls;j++){ if(koszt[lista[j].d]==-1){ koszt[lista[j].d]=koszt[kolejka[pocz_kol]]+*(lista[j].c); zysk=(long long)(miasto[lista[j].d].c)-koszt[lista[j].d]; if(zysk>maks){ maks=zysk; maksind=lista[j].d; }else if(zysk==maks && maksind>lista[j].d){ maksind=lista[j].d; } kolejka[kon_kol]=lista[j].d; kon_kol++; } } pocz_kol++; } printf("%d ",maksind+1); curr=maksind; } } #ifdef DEBUG void printState(){ for(ui i=0;i<n;i++){ fprintf(stderr,"Miasto %2u (banany: %3llu) (sasiezdzi: %2d):\n",i,miasto[i].c,miasto[i].ls); for(int j=0;j<miasto[i].ls;j++){ fprintf(stderr," (%2d) ===%-2llu==>%2d\n",miasto[i].d[j].s,*miasto[i].d[j].c,miasto[i].d[j].d); } } printf("______________________________________________________________\n"); } #endif int main(){ scanf("%d%d",&n,&q); p=new drogaT[2*(n-1)]; miasto=new miastoT[n]; cennik=new unsigned long long[n-1]; for(ui i=0;i<n;i++){ scanf("%llu",&miasto[i].c); miasto[i].ls=0; miasto[i].d=NULL; } for(ui i=0;i<n-1;i++){ scanf("%d%d%llu",&p[2*i].s,&p[2*i].d,&cennik[i]); p[2*i].s--; p[2*i].d--; p[2*i].c=&cennik[i]; p[2*i+1].s=p[2*i].d; p[2*i+1].d=p[2*i].s; p[2*i+1].c=p[2*i].c; } std::sort(p,p+2*(n-1),cmp); int curr=0; for(ui i=0;i<2*(n-1);i++){ if(p[i].s==curr){ miasto[curr].d=&p[i]; curr++; } //fprintf(stderr," %d %d %llu sorted?\n",p[i].s,p[i].d,*p[i].c); if( i+1<2*(n-1) && p[i+1].s==curr ){ miasto[curr-1].ls=int(&p[i+1]-miasto[curr-1].d); //fprintf(stderr," %d %d <<<\n",curr-1,miasto[curr-1].ls); } } miasto[curr-1].ls=int(p+2*(n-1)-miasto[curr-1].d); solve_b(); return 0; } |