Submission #289681

#TimeUsernameProblemLanguageResultExecution timeMemory
289681b00n0rpSwapping Cities (APIO20_swap)C++17
100 / 100
651 ms47608 KiB
/*
Soln:
Basically we need to find some 3-degree vertex or a cycle
and we want the minimum value of 
-> max(path from (x,y), path from x to the vertex,(3rd shortest edge or cycle edge))
First compute mst then use dp on tree
dp[u] = best such vertex in subtree of u
dp_par[u] = best such vertex outside subtree of u
*/
#include "swap.h"
#include <bits/stdc++.h>
using namespace std;
 
typedef long double LD;
typedef long long ll;
// #define int ll
#define pb push_back
#define mp make_pair
#define REP(i,n) for (int i = 0; i < n; i++)
#define FOR(i,a,b) for (int i = a; i < b; i++)
#define REPD(i,n) for (int i = n-1; i >= 0; i--)
#define FORD(i,a,b) for (int i = a; i >= b; i--)
#define remax(a,b) a = max(a,b)
#define remin(a,b) a = min(a,b)
#define all(v) v.begin(),v.end()
typedef map<int,int> mii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pii;
typedef vector<pii> vpii;
#define F first
#define S second
#define PQ(type) priority_queue<type>
#define PQD(type) priority_queue<type,vector<type>,greater<type> >
#define WL(t) while(t --)
#define SZ(x) ((int)(x).size())
#define runtime() ((double)clock() / CLOCKS_PER_SEC)
#define inrange(i,a,b) ((i>=min(a,b)) && (i<=max(a,b)))

#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

const int MAXN = 100005;
const int SQRTN = 1003;
const int LOGN = 22;
const double PI=acos(-1);
 
#ifdef int
const int INF=1e16;
#else
const int INF=1e9+5;
#endif
 
const int MOD = 1000000007;
const int FMOD = 998244353;
const double eps = 1e-9;


int n,m;
vpii adj[MAXN];
vpii extra[MAXN];
vector<pair<int,pii> > edges;

int dsusz[MAXN],dsupar[MAXN];

int find(int x){
	if(dsupar[x] == x) return x;
	return dsupar[x] = find(dsupar[x]);
}

void merge(int x,int y,int w){
	int x0 = find(x);
	int y0 = find(y);
	if(x0 == y0){
		extra[x].pb({y,w});
		extra[y].pb({x,w});
		return;
	}
	adj[x].pb({y,w});
	adj[y].pb({x,w});

	if(dsusz[x0] > dsusz[y0]) swap(x0,y0);
	dsupar[x0] = y0;
	dsusz[y0] += dsusz[x0]; 
}

pii par[MAXN][21];
int dep[MAXN],st[MAXN],fin[MAXN];
int dp[MAXN],dp_par[MAXN],val[MAXN];
int tim = 0;

void dfs0(int u,int p,int w,int d){
	val[u] = INF;
	if(extra[u].size()) remin(val[u],extra[u][0].S);
	if(adj[u].size() >= 3) remin(val[u],adj[u][2].S);
	dp[u] = val[u];
	dp_par[u] = val[u];
	st[u] = tim++;
	par[u][0] = {p,w};
	dep[u] = d;
	for(auto v:adj[u]){
		if(v.F != p){
			dfs0(v.F,u,v.S,d+1);
			remin(dp[u],max(v.S,dp[v.F]));
		}
	}
	fin[u] = tim;
}

void dfs_par(int u){
	vpii gg;
	for(auto v:adj[u]){
		if(v.F == par[u][0].F) continue;
		remin(dp_par[v.F],max(v.S,dp_par[u]));
		gg.pb({max(v.S,dp[v.F]),v.S});
	}
	sort(all(gg));
	for(auto v:adj[u]){
		if(v.F == par[u][0].F) continue;
		if(v.F == gg[0].S){
			if(gg.size() != 1){
				remin(dp_par[v.F],max(v.S,gg[1].F));
			}
		}
		else{
			remin(dp_par[v.F],max(v.S,gg[0].F));
		}
		dfs_par(v.F);
	}
}

void init(int N, int M,vi U, vi V, vi W) {
	n = N;
	m = M;
	REP(i,m) edges.pb({W[i],{U[i],V[i]}});
	REP(i,N){
		dsusz[i] = 1;
		dsupar[i] = i;
	}
	sort(all(edges));
	REP(i,m) merge(edges[i].S.F,edges[i].S.S,edges[i].F);
	tim = 0;
	dfs0(1,1,0,0);
	dfs_par(1);
	FOR(j,1,21){
		REP(i,n){
			par[i][j].F = par[par[i][j-1].F][j-1].F;
			par[i][j].S = max(par[i][j-1].S,par[par[i][j-1].F][j-1].S);
		}
	}
}

int lca(int u,int v){
	if(dep[u] < dep[v]) swap(u,v);
	int res = 0;
	FORD(j,20,0){
		if(dep[u]-(1<<j) >= dep[v]){
			remax(res,par[u][j].S);
			u = par[u][j].F;
		}
	}
	if(u == v) return res;
	FORD(j,20,0){
		if(par[u][j].F != par[v][j].F){
			remax(res,par[u][j].S);
			remax(res,par[v][j].S);
			u = par[u][j].F;
			v = par[v][j].F;
		}
	}
	remax(res,par[u][0].S);
	remax(res,par[v][0].S);
	return res;
}

int getMinimumFuelCapacity(int x, int y){
	int ans = lca(x,y);
	remax(ans,min(dp[x],dp_par[x]));
	if(ans >= INF) return -1;
	return ans;	
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...