社区讨论
n^4爆搜过了求hack
P8817[CSP-S 2022] 假期计划参与者 6已保存回复 11
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 11 条
- 当前快照
- 1 份
- 快照标识符
- @lo7nydjn
- 此快照首次捕获于
- 2023/10/27 04:55 2 年前
- 此快照最后确认于
- 2023/10/27 04:55 2 年前
RT,这题数据范围明显不能 过但是考场的爆搜+剪枝碾过去了,求问这个算法怎么 hack。
思路:先 bfs 预处理出所有可以到达的点,把处理出来的边数组
思路:先 bfs 预处理出所有可以到达的点,把处理出来的边数组
random_shuffle 一下之后暴力 dfs 四个点,如果剩下的点全部填最大可能点权的还是 <=ans 就 return 剪枝。个人没找到卡的方式但是不排除是本人太菜了qwq代码:
C#include <cstdio>
#include <vector>
#include <algorithm>
#define N 2510
int n,m,k;long long a[N],f[9],ans;
std::vector<int> e[N],g[N];
bool vis[N],home[N];
struct pair{int x,d;}q[N];
void bfs(int s)
{
int head=0,tail=0;
q[head++]=pair{s,k};
vis[s]=true;
while(head!=tail)
{
pair x=q[tail++];
e[s].push_back(x.x);
if(x.d>=0) for(auto i:g[x.x]) if(!vis[i])
{
vis[i]=true;
q[head++]=pair{i,x.d-1};
}
}
}
void dfs2(int x,int dep,long long tmp)
{
if(vis[x]||tmp+f[dep]<=ans) return;
if(dep==0) {if(home[x]) ans=tmp; return;}
vis[x]=true;
for(auto i:e[x]) dfs2(i,dep-1,tmp+a[i]);
vis[x]=false;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=2;i<=n;i++) scanf("%lld",a+i);
for(int i=0,u,v;i<m;i++) {scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u);}
//预处理可达点
for(int i=1;i<=n;i++)
{
bfs(i);
std::random_shuffle(e[i].begin(),e[i].end());
for(auto j:e[i]) vis[j]=false;
}
//双向边预处理可达1点
for(auto j:e[1]) home[j]=true;
//预处理前4大点
for(int i=4;i>=1;i--)
{
for(int j=2;j<=n;j++) if(a[j]>a[f[i]]&&!vis[j]) f[i]=j;
vis[f[i]]=true;
}
for(int i=1;i<=4;i++)
{
vis[f[i]]=false;
f[i]=f[i-1]+a[f[i]];
}
//爆搜
dfs2(1,4,0);
printf("%lld",ans);
}
回复
共 11 条回复,欢迎继续交流。
正在加载回复...