Submission #1368206

#TimeUsernameProblemLanguageResultExecution timeMemory
1368206stanirinaDreaming (IOI13_dreaming)C++20
100 / 100
69 ms25216 KiB
#include "dreaming.h"
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int> 
#define pb push_back
#define mp make_pair

using namespace std;

int n,m,l;
vector<int> u,v,w;
vector<vector<pii>> g,dg;
vector<int> col;
int color;
vector<vector<int>> comp;
vector<int> pnk;
vector<int> dnk;
vector<int> kzpnk;
vector<int> kzdnk;
vector<int> diamp;
vector<int> diamk;
vector<int> diamd;
vector<bool> nadiam;
vector<int> koren;
vector<int> iddist;
int nvkomp;


///prvo za svaku komponentu odredjujemo sta nam treba
///imamo niz col, koji odrzava koji cvor je u kojoj komponenti
/// za to nam treba i graf, gde imamo vector vector parova
/// pustimo dfs za odredjivanje komponenti, klasicno
///za svaku komponentu treba da odredimo dijametar (od kog do kog cvora) i njegovu duzinu
///to radimo dpom, za svaki cvor cuvamo prvi i drugi najduzi krak, njihovu duzinu i list do kog idu
/// sada treba da odredimo sve cvorove koji pripadaju dijametru
///to uradimo tako sto pustimo dfs iz nekog cvora, oznacimo drugi kraj sa true, i ako je neki cvor dete true onda je i njegov roditelj
/// onda pravimo drugi graf, tako sto iz pocetnog uklanjamo sve cvorove koji nisu u dijametru
/// zatim za svaku komponentu pocnemo iz jednog lista i idemo putem, pritom odredjujuci razdaljinu do jednog i drugog kraja
/// cuvajuci pritom idealnu najvecu distancu i cvor odakle je ona
/// zatim odredimo komponentu koja ima najveci najduzi krak
///nju proglasavamo za centralnu
///ans na pocetku postavimo na najveci dijametar
///zatim proverimo za zbir najduzeg kraka centralne komp i l i najduzeg kraka svake druge komp
///zatim odredimo od ostalih (bez centralne) kom dve najvece (sa najduzim krakom) i dodamo dva l
///vratimo odgovor

void dfs(int c){
	if(col[c]!=-1)return;
	
	col[c]=color;
	for(auto a:g[c]){
		if(col[a.fi]!=-1)continue;
		dfs(a.fi);//cout<<c<<' ';
	}
}

void dp(int c, int p){
	kzpnk[c]=c;
	kzdnk[c]=c;
	for(auto a:g[c]){
		if(a.fi==p)continue;
		dp(a.fi,c);
		if(a.se+pnk[a.fi]>=pnk[c]){
			dnk[c]=pnk[c];
			kzdnk[c]=kzdnk[c];
			pnk[c]=pnk[a.fi]+a.se;
			kzpnk[c]=kzpnk[a.fi];
		}
		else if(a.se+pnk[a.fi]>=dnk[c]){
			dnk[c]=a.se+pnk[a.fi];
			kzdnk[c]=kzpnk[a.fi];
		}
	}
}

void popuni(int c, int p){
	if(nadiam[c])return;
	for(auto a:g[c]){
		if(a.fi==p)continue;
		popuni(a.fi,c);
		if(nadiam[a.fi])nadiam[c]=true;
	}
}

int travelTime(int N, int M, int L, int U[], int V[], int W[]) {
	n=N;m=M;l=L;
	v.resize(m);
	u.resize(m);
	w.resize(m);
	for(int i=0;i<m;i++){
		v[i]=V[i];
		u[i]=U[i];
		w[i]=W[i];
	}
	g.resize(n);
	color=0;
	for(int i=0;i<n;i++)g[i].clear();
	for(int i=0;i<m;i++){
		g[v[i]].pb(mp(u[i],w[i]));
		g[u[i]].pb(mp(v[i],w[i]));
	}
	//for(int i=0;i<n;i++){
	//	cout<<i<<": ";
	//	for(auto a:g[i])cout<<a.fi<<' ';
	//	cout<<endl;
	//}
	col.assign(n,-1);
	for(int i=0;i<n;i++){
		
		if(col[i]!=-1)continue;
		dfs(i);
		color++;
	}
	//for(int i=0;i<n;i++)cout<<col[i]<<' ';
	//cout<<endl;
	comp.resize(color);
	for(int i=0;i<color;i++){
		comp[i].clear();
	}
	for(int i=0;i<n;i++)comp[col[i]].pb(i);
	pnk.assign(n,0);
	dnk.assign(n,0);
	kzpnk.assign(n,-1);
	kzdnk.assign(n,-1);
	
	diamd.assign(color,-1);
	diamk.assign(color,-1);
	diamp.assign(color,-1);
	for(int i=0;i<color;i++){
		dp(comp[i][0],-1);
		for(auto a:comp[i]){
			if(pnk[a]+dnk[a]>diamd[i]){
				diamd[i]=pnk[a]+dnk[a];
				diamp[i]=kzpnk[a];
				diamk[i]=kzdnk[a];
			}
		}
	}
	//for(int i=0;i<n;i++)cout<<kzpnk[i]<<' '<<kzdnk[i]<<endl;
	//cout<<"aaaa"<<endl;
	//for(int i=0;i<color;i++)cout<<diamp[i]<<' '<<diamk[i]<<' '<<diamd[i]<<endl;
	//cout<<"dobro je"<<endl;
	nadiam.assign(n,false);
	for(int i=0;i<color;i++){
		nadiam[diamk[i]]=true;
		popuni(diamp[i],-1);
	}
	
	dg.resize(n);
	for(int i=0;i<n;i++)dg[i].clear();
	for(int i=0;i<n;i++){
		for(auto a:g[i]){
			if(nadiam[a.fi])dg[i].pb(a);
		}
	}
	
	koren.assign(color,-1);
	iddist.assign(color,0);
	for(int i=0;i<color;i++){
		iddist[i]=diamd[i];
		koren[i]=diamp[i];
		int tren=diamp[i];
		int prev=-1;
		int d1=diamd[i];
		int d2=0;
		if(comp[i].size()<=2)continue;
		while(tren!=diamk[i]){
			int raz;
			int tmp=tren;
			tie(tren,raz)=dg[tmp][0];
			if(tren==prev)tie(tren,raz)=dg[tmp][1];
			prev=tmp;
			d2+=raz;
			d1-=raz;
			if(max(d1,d2)<iddist[i]){
				iddist[i]=max(d1,d2);
				koren[i]=tren;
			}
		}
	}
	
	nvkomp=0;
	for(int i=0;i<color;i++){
		if(iddist[i]>iddist[nvkomp])nvkomp=i;
	}
	
	int ans=0;
	for(int i=0;i<color;i++)ans=max(ans,diamd[i]);
	for(int i=0;i<color;i++){
		if(i==nvkomp)continue;
		ans=max(ans,l+iddist[nvkomp]+iddist[i]);
	}
	if(color<=2)return ans;
	int dnvkomp=0;
	if(nvkomp==0)dnvkomp++;
	for(int i=0;i<color;i++){
		if(i==nvkomp)continue;
		if(iddist[dnvkomp]<iddist[i])dnvkomp=i;
	}
	for(int i=0;i<color;i++){
		if(i==nvkomp)continue;
		if(i==dnvkomp)continue;
		ans=max(ans,iddist[dnvkomp]+iddist[i]+l+l);
	}
	
    return ans;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...