Submission #106558

#TimeUsernameProblemLanguageResultExecution timeMemory
106558zbwwDesignated Cities (JOI19_designated_cities)C++14
100 / 100
1320 ms35292 KiB
#include <bits/stdc++.h>
using namespace std;
const int N = 200001;
const long long inf = 1000000000000000ll;
struct edge{
	int to,nxt;
	long long w;
}tree[N << 1];
int n,q,head[N],cnt = 0;
void addedge(int u,int v,long long w){
	edge x = {v,head[u],w};
	tree[head[u] = cnt++] = x;
}
template<class T>
void read(T &x){
	int sgn = 1;
	char ch;
	x = 0;
	for(ch = getchar();(ch < '0' || ch > '9') && ch != '-';ch = getchar());
	if(ch == '-')ch = getchar(),sgn = -1;
	for(;'0' <= ch && ch <= '9';ch = getchar())x = x * 10 + ch - '0';
	x *= sgn;
}
template<class T>
void write(T x){
	if(x < 0)putchar('-'),write(-x);
	else if(x < 10)putchar(x + '0');
	else write(x / 10),putchar(x % 10 + '0');
}
long long ans[N],depth[N],sz[N];
bool visited[N];
int size[N],child[N];
int find_centroid(int u,int fa,int total,int &weight,int &pos){
	int w = total - size[u];
	for(int i = head[u];i >= 0;i = tree[i].nxt){
		int v = tree[i].to;
		if(!visited[v] && v != fa){
			find_centroid(v,u,total,weight,pos);
			w = max(w,size[v]);
		}
	}
	if(w < weight)weight = w,pos = u;
}
void dfs1(int u,int edge){
	sz[u] = depth[u] = tree[edge ^ 1].w,child[u] = 0,size[u] = 1;
	for(int i = head[u];i >= 0;i = tree[i].nxt){
		int v = tree[i].to;
		if(!visited[v] && i != edge){
			dfs1(v,i ^ 1);
			size[u] += size[v],sz[u] += sz[v];
			if(!child[u] || depth[child[u]] < depth[v]){
				child[u] = v;
				depth[u] = tree[edge ^ 1].w + depth[child[u]];
			}
		}
	}
}
struct node{
	int belong;
	long long d;
	bool operator < (node other) const{
		return d > other.d;
	}
}chain[N];
int tot = 0;
void dfs2(int u,int fa,int root,int t){
	if(u == t){
		node x = {root,depth[u]};
		chain[++tot] = x;
	}
	if(child[u])dfs2(child[u],u,root,t);
	for(int i = head[u];i >= 0;i = tree[i].nxt){
		int v = tree[i].to;
		if(!visited[v] && v != fa && v != child[u])dfs2(v,u,root,v);
	}
}
void divide_and_conquer(int u,long long w){
	visited[u] = true,sz[u] = 0ll,size[u] = 1;
	node x = {u,0ll};
	chain[tot = 0] = x;
	for(int i = head[u];i >= 0;i = tree[i].nxt){
		int v = tree[i].to;
		if(!visited[v]){
			dfs1(v,i ^ 1);
			sz[u] += sz[v],size[u] += size[v];
			dfs2(v,u,v,v);
		}
	}
	sort(chain,chain + tot + 1);
	int p = 0;
	for(int i = 1;i <= tot;i++){
		if(chain[i].belong != chain[0].belong){
			p = i;
			break;
		}
	}
	long long total = 0ll;
	ans[1] = min(ans[1],sz[u] + w);
	for(int i = 0;i < p;i++){
		if(i >= 0)total += chain[i].d;
		ans[i + 2] = min(ans[i + 2],sz[u] - total - chain[p].d + w);
	}
	for(int i = p;i <= tot;i++){
		total += chain[i].d;
		ans[i + 1] = min(ans[i + 1],sz[u] - total + w);
	}
	for(int i = tot + 2;i <= size[u];i++)ans[i] = min(ans[i],sz[u] - total + w);
	for(int i = head[u];i >= 0;i = tree[i].nxt){
		int v = tree[i].to;
		if(!visited[v]){
			int weight = n,pos = v;
			find_centroid(v,u,size[v],weight,pos);
			divide_and_conquer(pos,w + sz[u] - sz[v] + tree[i ^ 1].w);
		}
	}
	visited[u] = false;
}
int main(){
	read(n);
	for(int i = 1;i <= n;i++)head[i] = -1;
	for(int i = 1;i < n;i++){
		int u,v;
		long long w1,w2;
		read(u),read(v);
		read(w1),read(w2);
		addedge(u,v,w1);
		addedge(v,u,w2);
	}
	for(int i = 1;i <= n;i++)ans[i] = inf;
	divide_and_conquer(1,0ll);
	read(q);
	for(int i = 1;i <= q;i++){
		int x;
		read(x);
		write(ans[x]),putchar('\n');
	}
	return 0;
}

Compilation message (stderr)

designated_cities.cpp: In function 'int find_centroid(int, int, int, int&, int&)':
designated_cities.cpp:43:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
#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...