제출 #421088

#제출 시각아이디문제언어결과실행 시간메모리
421088JasiekstrzRoad Closures (APIO21_roads)C++17
100 / 100
1907 ms504452 KiB
#include "roads.h"
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
const int NN=1e5;
const int SQ=100;
const long long INF=(long long)1e18+7;
vector<pair<int,int>> e[NN+10];
vector<pair<long long,long long>> *dp[NN+10]; // fi - parent destroyed, se - parent not destroyed
bool big(int x)
{
	return e[x].size()>SQ;
}
void dfs(int x,int p,int n)
{
	for(auto v:e[x])
	{
		if(v.fi!=p)
			dfs(v.fi,x,n);
	}
	if(big(x))
	{
		dp[x]=new vector<pair<long long,long long>>(n);
		vector<long long> tmp;
		tmp.reserve(e[x].size());
		// small k
		for(int k=0;k<=min(SQ,n-1);k++)
		{
			tmp.clear();
			(*dp[x])[k].fi=0;
			for(auto v:e[x])
			{
				if(v.fi==p)
					continue;
				(*dp[x])[k].fi+=(*dp[v.fi])[k].fi+v.se;
				tmp.push_back((*dp[v.fi])[k].se-(*dp[v.fi])[k].fi-v.se);
			}
			(*dp[x])[k].se=(*dp[x])[k].fi;
			sort(tmp.begin(),tmp.end());
			while(!tmp.empty() && tmp.back()>0)
				tmp.pop_back();
			for(size_t i=1;i<tmp.size();i++)
				tmp[i]+=tmp[i-1];
			if(!tmp.empty())
			{
				if(k-1>=0)
					(*dp[x])[k].fi+=tmp[min((int)tmp.size(),k)-1];
				if(k-2>=0)
					(*dp[x])[k].se+=tmp[min((int)tmp.size(),k-1)-1];
			}
			if(k==0)
				(*dp[x])[k].se=INF;
		}
		// big k
		vector<pair<int,int>> edg;
		long long ww=0;
		vector<long long> tmp2;
		for(auto v:e[x])
		{
			if(v.fi==p)
				continue;
			if(dp[v.fi]->size()==n)
				edg.push_back(v);
			else
			{
				ww+=v.se;
				tmp2.push_back(-v.se);
			}
		}
		sort(tmp2.begin(),tmp2.end());
		for(size_t i=1;i<tmp2.size();i++)
			tmp2[i]+=tmp2[i-1];
		for(int k=SQ+1;k<n;k++)
		{
			(*dp[x])[k].fi=0;
			tmp.clear();
			for(auto v:edg)
			{
				(*dp[x])[k].fi+=(*dp[v.fi])[k].fi+v.se;
				tmp.push_back((*dp[v.fi])[k].se-(*dp[v.fi])[k].fi-v.se);
			}
			(*dp[x])[k].se=(*dp[x])[k].fi;
			sort(tmp.begin(),tmp.end());
			while(!tmp.empty() && tmp.back()>0)
				tmp.pop_back();
			for(size_t i=1;i<tmp.size();i++)
				tmp[i]+=tmp[i-1];
			long long w1=(*dp[x])[k].fi;
			long long w2=(*dp[x])[k].se;
			for(int i=0;i<=tmp.size() && i<=k;i++)
			{
				w1=min(w1,(*dp[x])[k].fi+(i>0 ? tmp[i-1]:0)+
						(!tmp2.empty() && k-i>0 ? tmp2[min((int)tmp2.size(),k-i)-1]:0));
				if(i<k)
				{
					w2=min(w2,(*dp[x])[k].se+(i>0 ? tmp[i-1]:0)+
							(!tmp2.empty() && k-1-i>0 ? tmp2[min((int)tmp2.size(),k-1-i)-1]:0));
				}
			}
			(*dp[x])[k].fi=w1+ww;
			(*dp[x])[k].se=w2+ww;
		}
		for(auto v:e[x])
		{
			if(v.fi!=p)
				delete dp[v.fi];
		}
	}
	else
	{
		vector<pair<long long,long long>> dt(min(SQ+1,n));
		dt.resize(SQ+1);
		vector<long long> tmp;
		tmp.reserve(e[x].size());
		// small k
		for(int k=0;k<=min(SQ,n-1);k++)
		{
			tmp.clear();
			dt[k].fi=0;
			for(auto v:e[x])
			{
				if(v.fi==p)
					continue;
				dt[k].fi+=(*dp[v.fi])[k].fi+v.se;
				tmp.push_back((*dp[v.fi])[k].se-(*dp[v.fi])[k].fi-v.se);
			}
			dt[k].se=dt[k].fi;
			sort(tmp.begin(),tmp.end());
			while(!tmp.empty() && tmp.back()>0)
				tmp.pop_back();
			for(size_t i=1;i<tmp.size();i++)
				tmp[i]+=tmp[i-1];
			if(!tmp.empty())
			{
				if(k-1>=0)
					dt[k].fi+=tmp[min((int)tmp.size(),k)-1];
				if(k-2>=0)
					dt[k].se+=tmp[min((int)tmp.size(),k-1)-1];
			}
			if(k==0)
				dt[k].se=INF;
		}
		// big k
		bool big_son=false;
		for(auto v:e[x])
		{
			if(v.fi==p)
				continue;
			if(dp[v.fi]->size()==n)
			{
				if(big(v.fi))
				{
					for(auto &c:(*dp[v.fi]))
						c.fi=c.se=min(c.fi+v.se,c.se);
				}
				if(!big_son)
				{
					dp[x]=dp[v.fi];
					big_son=true;
				}
				else
				{
					for(int k=0;k<n;k++)
					{
						(*dp[x])[k].fi+=(*dp[v.fi])[k].fi;
						(*dp[x])[k].se+=(*dp[v.fi])[k].se;
					}
				}
			}
		}
		if(!big_son)
			dp[x]=new vector<pair<long long,long long>>(min(SQ+1,n));
		for(int i=0;i<=min(SQ,n-1);i++)
			(*dp[x])[i]=dt[i];
		for(auto v:e[x])
		{
			if(v.fi!=p && dp[v.fi]!=dp[x])
				delete dp[v.fi];
		}
	}
	return;
}
vector<long long> minimum_closure_costs(int N,vector<int> U,vector<int> V,vector<int> W)
{
	for(int i=0;i<N-1;i++)
	{
		e[U[i]].emplace_back(V[i],W[i]);
		e[V[i]].emplace_back(U[i],W[i]);
	}
	dfs(0,-1,N);
	vector<long long> ans(N);
	for(int i=0;i<N;i++)
	{
		if(i<(dp[0]->size()))
			ans[i]=(*dp[0])[i].fi;
		else
			ans[i]=0;
	}
	return ans;
}

컴파일 시 표준 에러 (stderr) 메시지

roads.cpp: In function 'void dfs(int, int, int)':
roads.cpp:63:23: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   63 |    if(dp[v.fi]->size()==n)
      |       ~~~~~~~~~~~~~~~~^~~
roads.cpp:91:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   91 |    for(int i=0;i<=tmp.size() && i<=k;i++)
      |                ~^~~~~~~~~~~~
roads.cpp:150:23: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  150 |    if(dp[v.fi]->size()==n)
      |       ~~~~~~~~~~~~~~~~^~~
roads.cpp: In function 'std::vector<long long int> minimum_closure_costs(int, std::vector<int>, std::vector<int>, std::vector<int>)':
roads.cpp:195:7: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  195 |   if(i<(dp[0]->size()))
      |      ~^~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...