[codeforces 1296F] Berland Beauty 难在题意的理解+树上暴力+map的耗时,可不是O(1)

[codeforces 1296F] Berland Beauty 难在题意的理解+树上暴力+map的耗时,可不是O(1)

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1296/problem/F

Problem Lang Verdict Time Memory
F - Berland Beauty GNU C++11 Accepted 904 ms 300 KB

//题意怎么读都读不懂,看了此文https://blog.csdn.net/weixin_42429718/article/details/104199284才明白
/*
(注意是路径上的最小值,看了好久的题,比如1到3路径最小值是3 假如2到3为3,但是1到2可以为5 满足1到3路径最小值为3! ) 这句话理解清楚了这个题就不是很难了
*/

样例解释如下

若某条轨道没有涉及,那么该轨道美景在[1,1000000]均可。Otherwise, print n−1 integers f1,f2,…,fn−1 (1≤fi≤106),

思路:

因为n只有5000,算法的时间复杂度O(n^2),所以对于每一个限制条件,我们都在路径上保存一下这条边的最大边权,然后我们记录一下这个限制条件中路径上经过的边的编号

最后再check一遍m次限制路径上的边权的最小值是否等于w即可

以下代码,参考了https://www.e-learn.cn/content/qita/3369013关键点,记录轨道时,同时记录轨道的位次。

#include <cstdio>
#define maxn 5010
using namespace std;
int n,m,head[maxn],tot,val[maxn],vis[maxn],d,flag,u[maxn],v[maxn],w[maxn],check;//val[]记录铁路美景
struct node{
	int to,next,seq;
}e[maxn*2];
void add_edge(int u,int v,int seq){
	tot++,e[tot].to=v,e[tot].seq=seq,e[tot].next=head[u],head[u]=tot;
}
int max(int a,int b){
	return a>b?a:b;
}
void dfs(int x,int w,int now){//从节点x开始遍历树。设置铁路美景值
	int v,b;
	vis[x]=now;
	if(x==d){//找到终点d
		flag=1;
		return;
	}
	for(b=head[x];b;b=e[b].next){
		v=e[b].to;
		if(!flag&&vis[v]!=now){
			dfs(v,w,now);
			if(flag){
				int pos=e[b].seq;
				val[pos]=max(val[pos],w);
			}
		}
	}
}
void judge(int x,int w,int now){//排查设置值 是否与 询问值 一致
	int v,b;
	vis[x]=now;
	if(x==d){//找到终点d
		flag=1;
		return;
	}
	for(b=head[x];b;b=e[b].next){
		v=e[b].to;
		if(!flag&&vis[v]!=now){
			judge(v,w,now);
			if(flag){
				int pos=e[b].seq;
				if(val[pos]==w)check=1;
			}
		}
	}
}
int main(){
	int i,a,b,l,r;
	scanf("%d",&n);
	for(i=1;i<=n-1;i++){
		scanf("%d%d",&a,&b);
		add_edge(a,b,i),add_edge(b,a,i);
	}
	scanf("%d",&m);
	for(i=1;i<=m;i++){//设置值
		scanf("%d%d%d",&u[i],&v[i],&w[i]);
		flag=0,d=v[i],dfs(u[i],w[i],i);
	}
	for(i=1;i<=m;i++){//检验
		flag=0,check=0,d=v[i],judge(u[i],w[i],i+m);
		if(check==0)break;
	}
	if(check==0)printf("-1\n");
	else{
		for(i=1;i<=n-1;i++)
			if(val[i]==0)val[i]=1;//至少得是1.   1<=fi<=10^6
		printf("%d",val[1]);
		for(i=2;i<=n-1;i++)printf(" %d",val[i]);
		printf("\n");
	}
	return 0;
}

//纯暴力,写得不好的代码,留存,以作纪念。
//Time limit exceeded on test 271   到这,应该可以完成使命了。

Problem Lang Verdict Time Memory
F - Berland Beauty GNU C++11 Time limit exceeded on test 271 3000 ms 700 KB

明白了一点,map的耗时,可不是O(1).

//纯暴力,写得不好的代码,留存,以作纪念。
//Time limit exceeded on test 271   到这,应该可以完成使命了。
#include <cstdio>
#include <map>
#define maxn 5010
using namespace std;
int n,m,head[maxn],tot,val[maxn],vis[maxn],d,flag,u[maxn],v[maxn],w[maxn],check;//val[]记录铁路美景
map<pair<int,int>,int> mp;//用来定位铁路的位次
struct node{
	int to,next;
}e[maxn*2];
void add_edge(int u,int v){
	tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
int max(int a,int b){
	return a>b?a:b;
}
void dfs(int x,int w,int now){//从节点x开始遍历树。设置铁路美景值
	int v,b;
	vis[x]=now;
	if(x==d){
		flag=1;
		return;
	}
	for(b=head[x];b;b=e[b].next){
		v=e[b].to;
		if(!flag&&vis[v]!=now){
			dfs(v,w,now);
			if(flag){
				int l,r,pos;
				if(x<v)l=x,r=v;
				else l=v,r=x;
				pos=mp[pair<int,int>(l,r)];
				val[pos]=max(val[pos],w);
			}
		}
	}
}
void judge(int x,int w,int now){//排查设置值 是否与 询问值 一致
	int v,b;
	vis[x]=now;
	if(x==d){
		flag=1;
		return;
	}
	for(b=head[x];b;b=e[b].next){
		v=e[b].to;
		if(!flag&&vis[v]!=now){
			judge(v,w,now);
			if(flag){
				int l,r,pos;
				if(x<v)l=x,r=v;
				else l=v,r=x;
				pos=mp[pair<int,int>(l,r)];
				if(val[pos]==w)check=1;
			}
		}
	}
}
int main(){
	int i,a,b,l,r;
	scanf("%d",&n);
	for(i=1;i<=n-1;i++){
		scanf("%d%d",&a,&b);
		add_edge(a,b),add_edge(b,a);
		if(a<b)l=a,r=b;//l<r
		else l=b,r=a;
		mp[pair<int,int>(l,r)]=i;
	}
	scanf("%d",&m);
	for(i=1;i<=m;i++){//设置值
		scanf("%d%d%d",&u[i],&v[i],&w[i]);
		flag=0,d=v[i],dfs(u[i],w[i],i);
	}
	for(i=1;i<=m;i++){//检验
		flag=0,check=0,d=v[i],judge(u[i],w[i],i+m);
		if(check==0)break;
	}
	if(check==0)printf("-1\n");
	else{
		for(i=1;i<=n-1;i++)
			if(val[i]==0)val[i]=1;//至少得是1.   1<=fi<=10^6
		printf("%d",val[1]);
		for(i=2;i<=n-1;i++)printf(" %d",val[i]);
		printf("\n");
	}
	return 0;
}
发布了537 篇原创文章 · 获赞 529 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/104268887