这题真的只能用bfs嘛?
查看原帖
这题真的只能用bfs嘛?
936120
1711Elegy楼主2023/10/16 16:52

我用的是dfs,只有50分,其他的都是没过点都是TLE

我在想有没有可能是我每次访问都要把所有站遍历一遍的问题,换成vector数组优化会不会好一点?

#include<bits/stdc++.h>
#include<queue>
#define repeat(i,x) for(it i=1;i<=x;i++)
using namespace std;
typedef long long it;//这是longlong 
it n,m,k; 
inline it read(){//快读 
	it x=0;bool k=true;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') k=false;
		ch=getchar();
	}
	while(isdigit(ch)){
		x*=10;x+=ch-'0';
		ch=getchar();
	}
	if(k) return x;
	else return ~(x-1);
}
it ans=-100000000;
it lib[2505];//用于存储每个景点的分数 
bool edge[2505][2505];//二位数组存边 
it vis[2505];//记忆化? 
//cur表示当前位置,num表示已经获得的分数,zhuan表示上一个景点到这里转了几站,sss表示已经到过的景点数 
void dfs(it cur,it num,it zhuan,it sss){
	if(zhuan>k) return;
	if(sss==4&&cur==1){//已经去了4个景点,并且能回家 
		ans=max(ans,num);
		return;
	}
	if(sss==4){//已经去了4个景点,还没回家 
		if(edge[cur][1]){//能到家 
			dfs(1,num,zhuan,sss);//回家 
		}
	}
	if(zhuan<k){//可以转站 
		for(it i=1;i<=n;i++){//遍历 
			if(edge[cur][i]||edge[i][cur]){//能到达的站 
				dfs(i,num,zhuan+1,sss);//此时分数不增加,但是转站次数加一 
			}
		}
	}
	if(sss<4){//要去下一个景点 
		for(it i=1;i<=n;i++){//遍历 
			if(!vis[i]&&(edge[cur][i]||edge[i][cur])){//这个景点还没玩过,并且可以到达 
				vis[i]=true;//访问 
				dfs(i,num+lib[i],0,sss+1);//此时要加上分数,并且转站数重置 
				vis[i]=false;//回溯 
			}
		}
	}
}
int main(){
	n=read(),m=read(),k=read();
	for(it i=2;i<=n;i++) lib[i]=read();
	repeat(i,m){
		it a,b;a=read(),b=read();
		edge[a][b]=true;//对存在的边进行标记 
		edge[b][a]=true;
	}
	vis[1]=true;//第一点因为不能算分数,所以标记已经访问过 
	dfs(1,0,0,0);
	cout<<ans;
}
2023/10/16 16:52
加载中...