結果
| 問題 |
No.848 なかよし旅行
|
| コンテスト | |
| ユーザー |
LayCurse
|
| 提出日時 | 2019-07-05 21:55:55 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 12,745 bytes |
| コンパイル時間 | 1,862 ms |
| コンパイル使用メモリ | 198,344 KB |
| 最終ジャッジ日時 | 2025-01-07 05:56:55 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 8 WA * 18 |
ソースコード
#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];
int dist0[2000];
int distP[2000];
int distQ[2000];
int distM[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);
for(i=0;i<N;i++){
distM[i] =max_L(distP[i], distQ[i]);
}
res = -1;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
s = dist0[i] + distM[i] + distM[j] + dist0[j];
if(s > T){
continue;
}
chmax(res, T - distM[i] - distM[j]);
}
}
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];
//
// int dist0[2000], distP[2000], distQ[2000], distM[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);
//
// rep(i,N) distM[i] = max(distP[i], distQ[i]);
//
// res = -1;
// rep(i,N) rep(j,N){
// s = dist0[i] + distM[i] + distM[j] + dist0[j];
// if(s > T) continue;
// res >?= T - distM[i] - distM[j];
// }
// if(dist0[P] + distP[Q] + distQ[0] <= T) res = T;
//
// wt(res);
// }
LayCurse