結果
問題 | No.1301 Strange Graph Shortest Path |
ユーザー |
![]() |
提出日時 | 2020-12-05 00:42:23 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 212 ms / 3,000 ms |
コード長 | 13,732 bytes |
コンパイル時間 | 3,289 ms |
コンパイル使用メモリ | 219,636 KB |
最終ジャッジ日時 | 2025-01-16 16:31:29 |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 33 |
ソースコード
#pragma GCC optimize ("Ofast")#include<bits/stdc++.h>using namespace std;void*wmem;char memarr[96000000];template<class S, class T> inline S min_L(S a,T b){return a<=b?a:b;}template<class S, class T> inline S max_L(S a,T b){return a>=b?a:b;}template<class T> inline void walloc1d(T **arr, int x, void **mem = &wmem){static int skip[16] = {0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};(*mem) = (void*)( ((char*)(*mem)) + skip[((unsigned long long)(*mem)) & 15] );(*arr)=(T*)(*mem);(*mem)=((*arr)+x);}template<class T> inline void walloc1d(T **arr, int x1, int x2, void **mem = &wmem){walloc1d(arr, x2-x1, mem);(*arr) -= x1;}inline int my_getchar_unlocked(){static char buf[1048576];static int s = 1048576;static int e = 1048576;if(s == e && e == 1048576){e = fread_unlocked(buf, 1, 1048576, stdin);s = 0;}if(s == e){return EOF;}return buf[s++];}inline void rd(int &x){int k;int m=0;x=0;for(;;){k = my_getchar_unlocked();if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){x=k-'0';break;}}for(;;){k = my_getchar_unlocked();if(k<'0'||k>'9'){break;}x=x*10+k-'0';}if(m){x=-x;}}inline void rd(long long &x){int k;int m=0;x=0;for(;;){k = my_getchar_unlocked();if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){x=k-'0';break;}}for(;;){k = my_getchar_unlocked();if(k<'0'||k>'9'){break;}x=x*10+k-'0';}if(m){x=-x;}}struct MY_WRITER{char buf[1048576];int s;int e;MY_WRITER(){s = 0;e = 1048576;}~MY_WRITER(){if(s){fwrite_unlocked(buf, 1, s, stdout);}}};MY_WRITER MY_WRITER_VAR;void my_putchar_unlocked(int a){if(MY_WRITER_VAR.s == MY_WRITER_VAR.e){fwrite_unlocked(MY_WRITER_VAR.buf, 1, MY_WRITER_VAR.s, stdout);MY_WRITER_VAR.s = 0;}MY_WRITER_VAR.buf[MY_WRITER_VAR.s++] = a;}inline void wt_L(char a){my_putchar_unlocked(a);}inline void wt_L(long long x){int s=0;int m=0;char f[20];if(x<0){m=1;x=-x;}while(x){f[s++]=x%10;x/=10;}if(!s){f[s++]=0;}if(m){my_putchar_unlocked('-');}while(s--){my_putchar_unlocked(f[s]+'0');}}template <class T> struct LHeap{int*hp;int*place;int size;T*val;void malloc(int N){hp = (int*)std::malloc(N*sizeof(int));place=(int*)std::malloc(N*sizeof(int));val=(T*)std::malloc(N*sizeof(T));}void malloc(int N, int ini){hp = (int*)std::malloc(N*sizeof(int));place=(int*)std::malloc(N*sizeof(int));val=(T*)std::malloc(N*sizeof(T));if(ini){init(N);}}void walloc(int N, void **mem=&wmem){walloc1d(&hp, N, mem);walloc1d(&place, N, mem);walloc1d(&val, N, mem);}void walloc(int N, int ini, void **mem=&wmem){walloc1d(&hp, N, mem);walloc1d(&place, N, mem);walloc1d(&val, N, mem);if(ini){init(N);}}void free(){std::free(hp);std::free(place);std::free(val);}void init(int N){int i;size=0;for(i=(0);i<(N);i++){place[i]=-1;}}void up(int n){int m;while(n){m=(n-1)/2;if(val[hp[m]]<=val[hp[n]]){break;}swap(hp[m],hp[n]);swap(place[hp[m]],place[hp[n]]);n=m;}}void down(int n){int m;for(;;){m=2*n+1;if(m>=size){break;}if(m+1<size&&val[hp[m]]>val[hp[m+1]]){m++;}if(val[hp[m]]>=val[hp[n]]){break;}swap(hp[m],hp[n]);swap(place[hp[m]],place[hp[n]]);n=m;}}void change(int n, T v){T f = val[n];val[n] = v;if(place[n]==-1){place[n] = size;hp[size++] = n;up(place[n]);}else{if(f < v){down(place[n]);}else if(f > v){up(place[n]);}}}int pop(void){int res = hp[0];place[res] = -1;size--;if(size){hp[0]=hp[size];place[hp[0]]=0;down(0);}return res;}};template<class FT, class CT> struct minCostFlows{int node;int*es;int*emem;int**edge;int**rev;FT**flow;FT f_eps;CT**cost;CT*potential;CT c_eps;LHeap<CT> hp;char*reached;CT*cur_cost;int*level;void malloc(int N){int i;es = (int*)std::malloc(N*sizeof(int));emem = (int*)std::malloc(N*sizeof(int));edge = (int**)std::malloc(N*sizeof(int*));rev = (int**)std::malloc(N*sizeof(int*));flow = (FT**)std::malloc(N*sizeof(FT*));cost = (CT**)std::malloc(N*sizeof(CT*));for(i=(0);i<(N);i++){emem[i] = 0;edge[i] = rev[i] = NULL;flow[i] = NULL;cost[i] = NULL;}hp.malloc(N);reached = (char*)std::malloc(N*sizeof(char));cur_cost = (CT*)std::malloc(N*sizeof(CT));potential = (CT*)std::malloc(N*sizeof(CT));level = (int*)std::malloc(N*sizeof(int));node = N;for(i=(0);i<(N);i++){es[i] = 0;}f_eps = (FT)1e-9;c_eps = (CT)1e-9;}void init(int N){int i;node = N;for(i=(0);i<(N);i++){es[i] = 0;}f_eps = (FT)1e-9;c_eps = (CT)1e-9;}void memoryExpand(int i, int sz){if(sz <= emem[i]){return;}sz =max_L(max_L(sz, 3), 2*emem[i]);emem[i] = sz;edge[i] = (int*)realloc(edge[i], sz*sizeof(int));rev[i] = (int*)realloc(rev[i], sz*sizeof(int));flow[i] = (FT*)realloc(flow[i], sz*sizeof(FT));cost[i] = (CT*)realloc(cost[i], sz*sizeof(CT));}void addEdge(int n1, int n2, FT f, CT c){int s1 = es[n1]++;int s2 = es[n2]++;if(s1 >= emem[n1]){memoryExpand(n1, es[n1]);}if(s2 >= emem[n2]){memoryExpand(n2, es[n2]);}edge[n1][s1] = n2;edge[n2][s2] = n1;rev[n1][s1] = s2;rev[n2][s2] = s1;flow[n1][s1] = f;flow[n2][s2] = 0;cost[n1][s1] = c;cost[n2][s2] = -c;}FT solve_do_flow(int i, int ed, FT flim){int j;int k;FT res = 0;FT tmp;FT send;CT nc;if(i == ed){return flim;}for(j=(0);j<(es[i]);j++){if(flow[i][j] <= f_eps){continue;}k = edge[i][j];if(reached[k]==0 || level[k] <= level[i]){continue;}nc = cur_cost[i] + cost[i][j] + potential[i] - potential[k];if(cur_cost[k] < nc - c_eps || cur_cost[k] > nc + c_eps){continue;}if(flim < -f_eps){send = flow[i][j];}else{send =min_L(flim, flow[i][j]);}tmp = solve_do_flow(k, ed, send);if(tmp < f_eps){continue;}res += tmp;flow[i][j] -= tmp;flow[k][rev[i][j]] += tmp;if(flim >= -f_eps){flim -= tmp;if(flim <= f_eps){break;}}}return res;}template<class FTS, class CTS> void solve(int st, int ed, FTS &fres, CTS &cres, FT flim = -1, CT clim = 0){int i;int j;int k;int l;FT f;CT nc;fres = 0;cres = 0;for(i=(0);i<(node);i++){potential[i] = 0;}for(;;){if(flim >= -f_eps && flim <= f_eps){break;}hp.init(node);for(i=(0);i<(node);i++){reached[i] = 0;}reached[st] = 1;cur_cost[st] = 0;l = 0;hp.change(st, cur_cost[st]);while(hp.size){i = hp.pop();level[i] = l++;for(j=(0);j<(es[i]);j++){if(flow[i][j] <= f_eps){continue;}k = edge[i][j];nc = cur_cost[i] + cost[i][j] + potential[i] - potential[k];if(reached[k]==0 || cur_cost[k] > nc+c_eps){reached[k] = 1;cur_cost[k] = nc;hp.change(k, cur_cost[k]);}}}if(reached[ed]==0){break;}if(flim==-2 && cur_cost[ed] + potential[ed] >= clim){break;}f = solve_do_flow(st, ed, flim);if(f <= f_eps){break;}for(i=(0);i<(node);i++){if(reached[i]){potential[i] += cur_cost[i];}}fres += f;cres += f * potential[ed];flim -= f;}}};int N;int M;int A[100000];int B[100000];long long C[100000];long long D[100000];int main(){int i;wmem = memarr;int f;long long c;minCostFlows<int,long long> flow;rd(N);rd(M);{int AlM5nNnR;for(AlM5nNnR=(0);AlM5nNnR<(M);AlM5nNnR++){rd(A[AlM5nNnR]);A[AlM5nNnR] += (-1);rd(B[AlM5nNnR]);B[AlM5nNnR] += (-1);rd(C[AlM5nNnR]);rd(D[AlM5nNnR]);}}flow.malloc(N);flow.init(N);for(i=(0);i<(M);i++){flow.addEdge(A[i], B[i], 1, C[i]);flow.addEdge(B[i], A[i], 1, C[i]);flow.addEdge(A[i], B[i], 1, D[i]);flow.addEdge(B[i], A[i], 1, D[i]);}flow.solve(0, N-1, f, c, 2);wt_L(c);wt_L('\n');return 0;}// cLay version 20201204-1 [beta]// --- original code ---// template<class FT, class CT>// struct minCostFlows {// int node;// int *es, *emem, **edge, **rev;// FT **flow, f_eps;// CT **cost, *potential, c_eps;//// LHeap<CT> hp;// char *reached;// CT *cur_cost;// int *level;//// void malloc(int N){// int i;// es = (int*)std::malloc(N*sizeof(int));// emem = (int*)std::malloc(N*sizeof(int));// edge = (int**)std::malloc(N*sizeof(int*));// rev = (int**)std::malloc(N*sizeof(int*));// flow = (FT**)std::malloc(N*sizeof(FT*));// cost = (CT**)std::malloc(N*sizeof(CT*));// rep(i,N){// emem[i] = 0;// edge[i] = rev[i] = NULL;// flow[i] = NULL;// cost[i] = NULL;// }//// hp.malloc(N);// reached = (char*)std::malloc(N*sizeof(char));// cur_cost = (CT*)std::malloc(N*sizeof(CT));// potential = (CT*)std::malloc(N*sizeof(CT));// level = (int*)std::malloc(N*sizeof(int));//// node = N;// rep(i,N) es[i] = 0;// f_eps = (FT)1e-9;// c_eps = (CT)1e-9;// }//// void init(int N){// int i;// node = N;// rep(i,N) es[i] = 0;// f_eps = (FT)1e-9;// c_eps = (CT)1e-9;// }//// void memoryExpand(int i, int sz){// if(sz <= emem[i]) return;// sz = max(sz, 3, 2emem[i]);// emem[i] = sz;// edge[i] = (int*)realloc(edge[i], sz*sizeof(int));// rev[i] = (int*)realloc(rev[i], sz*sizeof(int));// flow[i] = (FT*)realloc(flow[i], sz*sizeof(FT));// cost[i] = (CT*)realloc(cost[i], sz*sizeof(CT));// }//// void addEdge(int n1, int n2, FT f, CT c){// int s1 = es[n1]++;// int s2 = es[n2]++;// if(s1 >= emem[n1]) memoryExpand(n1, es[n1]);// if(s2 >= emem[n2]) memoryExpand(n2, es[n2]);// edge[n1][s1] = n2; edge[n2][s2] = n1;// rev[n1][s1] = s2; rev[n2][s2] = s1;// flow[n1][s1] = f; flow[n2][s2] = 0;// cost[n1][s1] = c; cost[n2][s2] = -c;// }//// FT solve_do_flow(int i, int ed, FT flim){// int j, k;// FT res = 0, tmp, send;// CT nc;//// if(i == ed){// return flim;// }// rep(j,es[i]){// if(flow[i][j] <= f_eps) continue;// k = edge[i][j];// if(reached[k]==0 || level[k] <= level[i]) continue;// nc = cur_cost[i] + cost[i][j] + potential[i] - potential[k];// if(cur_cost[k] < nc - c_eps || cur_cost[k] > nc + c_eps) continue;//// if(flim < -f_eps){// send = flow[i][j];// } else {// send = min(flim, flow[i][j]);// }// tmp = solve_do_flow(k, ed, send);// if(tmp < f_eps) continue;//// res += tmp;// flow[i][j] -= tmp;// flow[k][rev[i][j]] += tmp;//// if(flim >= -f_eps){// flim -= tmp;// if(flim <= f_eps) break;// }// }//// return res;// }//// template<class FTS, class CTS>// void solve(int st, int ed, FTS &fres, CTS &cres, FT flim = -1, CT clim = 0){// int i, j, k, l;// FT f;// CT nc;//// fres = 0;// cres = 0;// rep(i,node) potential[i] = 0;////// for(;;){// if(flim >= -f_eps && flim <= f_eps) break;// hp.init(node);// rep(i,node) reached[i] = 0;// reached[st] = 1;// cur_cost[st] = 0;// l = 0;// hp.change(st, cur_cost[st]);// while(hp.size){// i = hp.pop();// level[i] = l++;// rep(j, es[i]){// if(flow[i][j] <= f_eps) continue;// k = edge[i][j];// nc = cur_cost[i] + cost[i][j] + potential[i] - potential[k];// if(reached[k]==0 || cur_cost[k] > nc+c_eps){// reached[k] = 1;// cur_cost[k] = nc;// hp.change(k, cur_cost[k]);// }// }// }// if(reached[ed]==0) break;// if(flim==-2 && cur_cost[ed] + potential[ed] >= clim) break;// f = solve_do_flow(st, ed, flim);// if(f <= f_eps) break;//// rep(i,node) if(reached[i]) potential[i] += cur_cost[i];// fres += f;// cres += f * potential[ed];// flim -= f;// }// }// };////// int N, M, A[1d5], B[1d5]; ll C[1d5], D[1d5];// {// int f; ll c;// minCostFlows<int,ll> flow;// rd(N,M,(A--,B--,C,D)(M));// flow.malloc(N);// flow.init(N);// rep(i,M){// flow.addEdge(A[i], B[i], 1, C[i]);// flow.addEdge(B[i], A[i], 1, C[i]);// flow.addEdge(A[i], B[i], 1, D[i]);// flow.addEdge(B[i], A[i], 1, D[i]);// }// flow.solve(0, N-1, f, c, 2);// wt(c);// }