# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1184166 | ivaziva | Dreaming (IOI13_dreaming) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
#include "dreaming.h"
using namespace std;
#define MAXN 100001
#define int long long
int brkomp=0,timer=1,slucaj=-1;
vector<pair<int,int>> adj[MAXN];
int komponenta[MAXN],dist[MAXN];
int tin[MAXN],tout[MAXN],fenw[MAXN+1];
vector<int> nodes[MAXN];
vector<int> answers;
void dfs(int node,int pret)
{
komponenta[node]=brkomp;nodes[brkomp].push_back(node);
for (pair<int,int> par:adj[node])
{
int sled=par.first,w=par.second;if (sled==pret) continue;
dist[sled]=dist[node]+w;dfs(sled,node);
}
}
void dfs1(int node,int pret)
{
tin[node]=timer;timer++;
for (pair<int,int> par:adj[node])
{
int sled=par.first,w=par.second;if (sled==pret) continue;
dist[sled]=dist[node]+w;dfs1(sled,node);
}
tout[node]=timer-1;
}
void update(int pos,int val)
{
for (int i=pos;i<=timer+1;i+=i&(-i)) fenw[i]+=val;
}
int query(int pos)
{
int sum=0;
for (int i=pos;i>0;i-=i&(-i)) sum+=fenw[i];
return sum;
}
void resi(int komp,int n)
{
int maxdist=0,maxnode=-1;
for (int node:nodes[komp])
{
if (dist[node]>maxdist) {maxdist=dist[node];maxnode=node;}
}
timer=1;dist[maxnode]=0;dfs1(maxnode,0);int len=0,sol=len;
for (int i=1;i<=timer+1;i++) fenw[i]=0;
for (int node:nodes[komp]) len=max(len,dist[node]);
for (int node:nodes[komp])
{
if (dist[node]==len) {update(tin[node],1);update(tout[node]+1,-1);}
}
for (int node=1;node<=n;node++)
{
int value=max(dist[node],len-dist[node]);if (value>=len) continue;
int broj=query(tout[node])-query(tin[node]-1);if (broj>0) sol=value;
}
answers.push_back(sol);slucaj=len;return;
}
int travelTime(int n,int m,int l,int a[],int b[],int t[])
{
for (int i=0;i<m;i++) {int node1=a[i]+1,node2=b[i]+1,weight=t[i];adj[node1].push_back({node2,weight});adj[node2].push_back({node1,weight});}
for (int node=1;node<=n;node++)
{
if (komponenta[node]==0) {brkomp++;dfs(node,0);}
}
for (int komp=1;komp<=brkomp;komp++) resi(komp,n);
sort(answers.begin(),answers.end());
if (answers.size()==1) return slucaj;
return l+answers[answers.size()-1]+answers[answers.size()-2];
}