我用的是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;
}