제출 #700873

#제출 시각아이디문제언어결과실행 시간메모리
700873kusmetliq경주 (Race) (IOI11_race)C++14
100 / 100
806 ms38316 KiB
#include<bits/stdc++.h>
using namespace std;

const int maxN=200005;
const long long big=100000000000000;

long long k;
long long minans=INT_MAX;
vector<int>a[maxN];
int sus[2*maxN],dist[2*maxN];
long long path[1000001];
bool used[maxN];
int sz[maxN];

long long min(long long a,long long b) {
    return (a<b?a:b);
}

int upd_sz(int n,int parent=-1) {
    sz[n]=1;
    for(int ii:a[n]) {
        int i=sus[ii];
        if(i!=parent && used[i]==0)sz[n]+=upd_sz(i,n);
    }
    return sz[n];
}

int find_cen(int n,int siz,int parent=-1) {
    for(int ii:a[n]) {
        int i=sus[ii];
        if(used[i]==0 && sz[i]>siz/2 && i!=parent)return find_cen(i,siz,n);
    }
    return n;
}

void upd_ans(int n,int depth,long long distance,int parent=-1) {
    if(k-distance>=0)minans=min(minans,depth+path[k-distance]+big);
    for(int ii:a[n]) {
        int i=sus[ii];
        if(used[i]==0 && i!=parent) {
            upd_ans(i,depth+1,distance+dist[ii],n);
        }
    }
}
vector<int>vec;
void upd_score(int n,int depth,long long distance,int parent=-1) {
    if(distance<=k){path[distance]=min(path[distance],depth-big);vec.push_back(distance);}
    for(int ii:a[n]) {
        int i=sus[ii];
        if(used[i]==0 && i!=parent) {
            upd_score(i,depth+1,distance+dist[ii],n);
        }
    }
}

void dfs(int n) {
    int c=find_cen(n,upd_sz(n));
    used[c]=1;
    path[0]=-big;
    vec.clear();
    for(int ii:a[c]) {
        int i=sus[ii];
        if(used[i]==0) {
            upd_ans(i,1,dist[ii]);
            upd_score(i,1,dist[ii]);
        }
    }
    for(int i:vec)path[i]=0;
    for(int ii:a[c]) {
        int i=sus[ii];
        if(used[i]==0)dfs(i);
    }
}

int best_path(int N,int K,int H[][2],int L[]) {
    k=K;
    for(int i=0;i<N-1;i++) {
        a[H[i][0]].push_back(i*2);
        a[H[i][1]].push_back(i*2+1);
        sus[i*2]=H[i][1];
        sus[i*2+1]=H[i][0];
        dist[i*2]=dist[i*2+1]=L[i];
    }
    dfs(0);
    if(minans==INT_MAX)return -1;
    else return minans;
}
/**
int main() {
    int n;
    cin>>n>>k;
    for(int i=0;i<n-1;i++) {
        int z;
        int x,y;cin>>x>>y>>z;
        a[x].push_back(y);
        a[y].push_back(x);
        dist[{x,y}]=dist[{y,x}]=z;
    }
    dfs(0);
    if(minans==INT_MAX)cout<<-1<<endl;
    else cout<<minans<<endl;
    return 0;
}*/
/**
4 3
0 1 1
1 2 2
1 3 4
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...