結果
問題 | No.848 なかよし旅行 |
ユーザー | LayCurse |
提出日時 | 2019-07-05 22:01:51 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 20 ms / 2,000 ms |
コード長 | 12,663 bytes |
コンパイル時間 | 2,270 ms |
コンパイル使用メモリ | 205,400 KB |
実行使用メモリ | 7,552 KB |
最終ジャッジ日時 | 2024-11-08 00:48:35 |
合計ジャッジ時間 | 3,571 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 18 ms
7,552 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 2 ms
5,248 KB |
testcase_08 | AC | 2 ms
5,248 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 9 ms
5,248 KB |
testcase_12 | AC | 11 ms
5,248 KB |
testcase_13 | AC | 14 ms
5,888 KB |
testcase_14 | AC | 7 ms
5,248 KB |
testcase_15 | AC | 12 ms
5,632 KB |
testcase_16 | AC | 19 ms
7,552 KB |
testcase_17 | AC | 13 ms
6,016 KB |
testcase_18 | AC | 8 ms
5,248 KB |
testcase_19 | AC | 8 ms
5,248 KB |
testcase_20 | AC | 6 ms
5,248 KB |
testcase_21 | AC | 15 ms
6,656 KB |
testcase_22 | AC | 15 ms
7,296 KB |
testcase_23 | AC | 6 ms
5,248 KB |
testcase_24 | AC | 2 ms
5,248 KB |
testcase_25 | AC | 20 ms
7,424 KB |
testcase_26 | AC | 2 ms
5,248 KB |
testcase_27 | AC | 2 ms
5,248 KB |
testcase_28 | AC | 2 ms
5,248 KB |
testcase_29 | AC | 2 ms
5,248 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; void *wmem; template<class S, class T> inline S max_L(S a,T b){ return a>=b?a:b; } inline void rd(int &x){ int k, m=0; x=0; for(;;){ k = getchar_unlocked(); if(k=='-'){ m=1; break; } if('0'<=k&&k<='9'){ x=k-'0'; break; } } for(;;){ k = 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, m=0; x=0; for(;;){ k = getchar_unlocked(); if(k=='-'){ m=1; break; } if('0'<=k&&k<='9'){ x=k-'0'; break; } } for(;;){ k = getchar_unlocked(); if(k<'0'||k>'9'){ break; } x=x*10+k-'0'; } if(m){ x=-x; } } inline void wt_L(char a){ putchar_unlocked(a); } inline void wt_L(long long x){ char f[20]; int m=0, s=0; if(x<0){ m=1; x=-x; } while(x){ f[s++]=x%10; x/=10; } if(!s){ f[s++]=0; } if(m){ putchar_unlocked('-'); } while(s--){ putchar_unlocked(f[s]+'0'); } } template<class S, class T> inline S chmax(S &a, T b){ if(a<b){ a=b; } return a; } template <class T> struct DijkstraHeap{ T *val; char *visited; int *hp, *place, size; void malloc(int N){ hp = (int*)std::malloc(N*sizeof(int)); place = (int*)std::malloc(N*sizeof(int)); visited = (char*)std::malloc(N*sizeof(char)); val = (T*)std::malloc(N*sizeof(T)); } void free(){ std::free(hp); std::free(place); std::free(visited); std::free(val); } void walloc(int N, void **mem=&wmem){ hp = (int*)(*mem); place = hp + N; visited = (char*)(place+N); val = (T*)(visited+N); *mem = val + N; } void init(int N){ int i; size = 0; for(i=0;i<N;i++){ place[i]=-1; } for(i=0;i<N;i++){ visited[i]=0; } } 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){ if(visited[n]||(place[n]>=0&&val[n]<=v)){ return; } val[n]=v; if(place[n]==-1){ place[n]=size; hp[size++]=n; up(place[n]); } else{ 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); } visited[res]=1; return res; } } ; struct graph{ int N, **edge, *es; void setEdge(int N__, int M, int A[], int B[], void **mem = &wmem){ int i; N = N__; es = (int*)(*mem); edge = (int**)(es+N); edge[0] = (int*)(edge+N); for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ es[A[i]]++; es[B[i]]++; } for(i=1;i<N;i++){ edge[i] = edge[i-1] + es[i-1]; } (*mem) = edge[N-1] + es[N-1]; for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ edge[A[i]][es[A[i]]++] = B[i]; edge[B[i]][es[B[i]]++] = A[i]; } } void setDirectEdge(int N__, int M, int A[], int B[], void **mem = &wmem){ int i; N = N__; es = (int*)(*mem); edge = (int**)(es+N); edge[0] = (int*)(edge+N); for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ es[A[i]]++; } for(i=1;i<N;i++){ edge[i] = edge[i-1] + es[i-1]; } (*mem) = edge[N-1] + es[N-1]; for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ edge[A[i]][es[A[i]]++] = B[i]; } } graph reverse(void **mem = &wmem){ graph g; int i, j, k; g.N = N; g.es = (int*)(*mem); g.edge = (int**)(g.es + N); g.edge[0] = (int*)(g.edge + N); for(i=0;i<N;i++){ g.es[i] = 0; } for(i=0;i<N;i++){ for(j=0;j<es[i];j++){ g.es[edge[i][j]]++; } } for(i=1;i<N;i++){ g.edge[i] = g.edge[i-1] + g.es[i-1]; } *mem = g.edge[N-1] + g.es[N-1]; for(i=0;i<N;i++){ g.es[i] = 0; } for(i=0;i<N;i++){ for(j=0;j<es[i];j++){ k = edge[i][j]; g.edge[k][g.es[k]++] = i; } } return g; } graph reduce(int tn, int ind[], int self_e = 0, int dep_e = 0, void **mem = &wmem){ graph g; int M=0, i, j, k, x, y; pair<int,int> *A; for(i=0;i<N;i++){ M += es[i]; } A = (pair<int,int>*)((int*)((int**)(*mem) + tn) + tn + M); M = 0; for(i=0;i<N;i++){ x = ind[i]; if(x < 0){ continue; } for(j=0;j<es[i];j++){ y = ind[edge[i][j]]; if(y < 0){ continue; } if(self_e==0 && x==y){ continue; } A[M++] = make_pair(x, y); } } if(dep_e==0){ sort(A, A+M); k = 0; for(i=0;i<M;i++){ if(k && A[k-1]==A[i]){ continue; } A[k++] = A[i]; } M = k; } g.N = tn; g.es = (int*)(*mem); g.edge = (int**)(g.es + tn); g.edge[0] = (int*)(g.edge + tn); for(i=0;i<tn;i++){ g.es[i] = 0; } for(i=0;i<M;i++){ g.es[A[i].first]++; } for(i=1;i<tn;i++){ g.edge[i] = g.edge[i-1] + g.es[i-1]; } *mem = g.edge[tn-1] + g.es[tn-1]; for(i=0;i<tn;i++){ g.es[i] = 0; } for(i=0;i<M;i++){ j = A[i].first; k = A[i].second; g.edge[j][g.es[j]++] = k; } return g; } void getDist(int root, int res[], void *mem = wmem){ int i, j, k, *q, s, z; q=(int*)mem; for(i=0;i<N;i++){ res[i]=-1; } res[root]=0; s=0; z=1; q[0]=root; while(z){ i=q[s++]; z--; for(j=0;j<es[i];j++){ k=edge[i][j]; if(res[k]>=0){ continue; } res[k]=res[i]+1; q[s+z++]=k; } } } inline int sccDFS(int num[], int st, int mx){ int i, j; num[st]=-2; for(i=0;i<es[st];i++){ j=edge[st][i]; if(num[j]==-1){ mx=sccDFS(num,j,mx); } } num[st]=mx; return mx+1; } int scc(int res[], void *mem = wmem){ graph r; int i, j, k, *nrv, *num, ret=0, *st, st_size; r = reverse(&mem); st = (int*)mem; num = st+N; nrv = num + N; for(i=0;i<N;i++){ res[i] = num[i] = -1; } k = 0; for(i=0;i<N;i++){ if(num[i]==-1){ k = sccDFS(num,i,k); } } for(i=0;i<N;i++){ nrv[num[i]] = i; } for(k=N-1;k>=0;k--){ i=nrv[k]; if(res[i]>=0){ continue; } res[i]=ret; st_size=0; st[st_size++]=i; while(st_size){ i=st[--st_size]; for(j=0;j<r.es[i];j++){ if(res[r.edge[i][j]]==-1){ res[r.edge[i][j]]=ret; st[st_size++]=r.edge[i][j]; } } } ret++; } return ret; } inline void bccDFS(int v, int u, int *res, int *rt, int &rts, int *S, int &Ss, int *inS, int *num, int &tm){ int i, k; num[v] = ++tm; S[Ss++] = v; inS[v] = 1; rt[rts++] = v; for(i=0;i<es[v];i++){ int w=edge[v][i]; if(!num[w]){ bccDFS(w, v, res, rt, rts, S, Ss, inS, num, tm); } else if(u != w && inS[w]){ while(num[rt[rts-1]] > num[w]){ rts--; } } } if(v == rt[rts-1]){ k = S[Ss-1]; for(;;){ int w=S[--Ss]; inS[w] = 0; res[w] = k; if(v==w){ break; } } rts--; } } int bcc(int res[], void *mem=wmem){ int *S, Ss=0, i, *inS, k, *num, *rt, rts=0, tm=0; pair<int,int> *arr; num = (int*)mem; rt = num + N; S = rt + N; inS = S + N; memset(num, 0, sizeof(int)*N); memset(inS, 0, sizeof(int)*N); for(i=0;i<N;i++){ if(!num[i]){ bccDFS(i, N, res, rt, rts, S, Ss, inS, num, tm); } } arr = (pair<int,int>*)mem; for(i=0;i<N;i++){ arr[i].first = res[i]; arr[i].second = i; } sort(arr, arr+N); k = 0; for(i=0;i<N;i++){ if(i && arr[i].first != arr[i-1].first){ k++; } res[arr[i].second] = k; } return k+1; } } ; template<class T> struct wgraph{ T **cost; graph g; int N, **edge, *es; void setEdge(int N__, int M, int A[], int B[], T C[], void **mem = &wmem){ int i; N = N__; es = (int*)(*mem); for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ es[A[i]]++; es[B[i]]++; } edge = (int**)(es+N); edge[0] = (int*)(edge+N); for(i=1;i<N;i++){ edge[i] = edge[i-1] + es[i-1]; } cost = (T**)(edge[N-1]+es[N-1]); cost[0] = (T*)(cost+N); for(i=1;i<N;i++){ cost[i] = cost[i-1] + es[i-1]; } (*mem) = cost[N-1] + es[N-1]; for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ edge[A[i]][es[A[i]]] = B[i]; edge[B[i]][es[B[i]]] = A[i]; cost[A[i]][es[A[i]]++] = C[i]; cost[B[i]][es[B[i]]++] = C[i]; } g.N = N; g.es = es; g.edge = edge; } void setDirectEdge(int N__, int M, int A[], int B[], T C[], void **mem = &wmem){ int i; N = N__; es = (int*)(*mem); for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ es[A[i]]++; } edge = (int**)(es+N); edge[0] = (int*)(edge+N); for(i=1;i<N;i++){ edge[i] = edge[i-1] + es[i-1]; } cost = (T**)(edge[N-1]+es[N-1]); cost[0] = (T*)(cost+N); for(i=1;i<N;i++){ cost[i] = cost[i-1] + es[i-1]; } (*mem) = cost[N-1] + es[N-1]; for(i=0;i<N;i++){ es[i] = 0; } for(i=0;i<M;i++){ edge[A[i]][es[A[i]]] = B[i]; cost[A[i]][es[A[i]]++] = C[i]; } g.N = N; g.es = es; g.edge = edge; } template<class S> void getDist(int root, S res[], S unreachable = -1, void *mem = wmem){ DijkstraHeap<S> hp; int i, j; hp.walloc(N, &mem); hp.init(N); hp.change(root,0); while(hp.size){ i = hp.pop(); for(j=0;j<es[i];j++){ hp.change(edge[i][j], hp.val[i]+cost[i][j]); } } for(i=0;i<N;i++){ res[i] = (hp.visited[i] ? hp.val[i] : unreachable); } } template<class S> void getDistForest(int root, S res[], S unreachable = -1, void *mem = wmem){ char *r; int i, j, k, *q, s, z; q=(int*)mem; r=(char*)(q+N); for(i=0;i<N;i++){ r[i]=0; } res[root]=0; r[root]=1; s=0; z=1; q[0]=root; while(z){ i=q[s++]; z--; for(j=0;j<es[i];j++){ k=edge[i][j]; if(r[k]){ continue; } res[k]=res[i]+cost[i][j]; r[k]=1; q[s+z++]=k; } } for(i=0;i<N;i++){ if(!r[i]){ res[i]=unreachable; } } } } ; char memarr[96000000]; int N; int M; int P; int Q; int T; int A[100000]; int B[100000]; long long C[100000]; long long dist0[2000]; long long distP[2000]; long long distQ[2000]; int main(){ int i, j, k; long long res, s, tmp; wgraph<long long> g; wmem = memarr; rd(N); rd(M); rd(P); rd(Q); rd(T); { int Lj4PdHRW; for(Lj4PdHRW=0;Lj4PdHRW<M;Lj4PdHRW++){ rd(A[Lj4PdHRW]); rd(B[Lj4PdHRW]); rd(C[Lj4PdHRW]); } } P--; Q--; for(i=0;i<M;i++){ A[i]--; B[i]--; } g.setEdge(N, M, A, B, C); g.getDist(0, dist0); g.getDist(P, distP); g.getDist(Q, distQ); res = -1; for(i=0;i<N;i++){ for(j=i;j<N;j++){ tmp =max_L(distP[i]+distP[j], distQ[i]+distQ[j]); s = dist0[i] + tmp + dist0[j]; if(s > T){ continue; } chmax(res, T - tmp); } } if(dist0[P] + distP[Q] + distQ[0] <= T){ res = T; } wt_L(res); wt_L('\n'); return 0; } // cLay varsion 20190630-1 // --- original code --- // int N, M, P, Q, T, A[1d5], B[1d5]; ll C[1d5]; // // ll dist0[2000], distP[2000], distQ[2000]; // // { // int i, j, k; // ll res, tmp, s; // wgraph<ll> g; // // rd(N,M,P,Q,T,(A,B,C)(M)); // P--; Q--; // rep(i,M) A[i]--, B[i]--; // // g.setEdge(N, M, A, B, C); // g.getDist(0, dist0); // g.getDist(P, distP); // g.getDist(Q, distQ); // // res = -1; // rep(i,N) rep(j,i,N){ // tmp = max(distP[i]+distP[j], distQ[i]+distQ[j]); // s = dist0[i] + tmp + dist0[j]; // if(s > T) continue; // res >?= T - tmp; // } // if(dist0[P] + distP[Q] + distQ[0] <= T) res = T; // // wt(res); // }