社区讨论
求助:题解中有一处代码看不懂,这道题只有俩个题解
学术版参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo9lodl4
- 此快照首次捕获于
- 2023/10/28 13:27 2 年前
- 此快照最后确认于
- 2023/10/28 13:27 2 年前
题目是洛谷的CF212E IT Restaurants。
这道题主要是不太能理解背包环节中的“”是干什么的QAQ。
完整AC代码如下,蒟蒻添加了若干注释希望帮助大佬快速理解代码
CPP#include <bits/stdc++.h>
using namespace std;
#define For(i, a, b) for(int i=a; i<=b; i++)
const int maxn = 5050;
struct Edge{
int to, nxt;
}edge[maxn];
int n, cnt = 0, ans1=0;
int head[maxn], indegree[maxn], f[maxn], size1[maxn], ans[maxn];
bool vis[maxn];
void add_edge(int u, int v){
edge[++cnt].to = v;
edge[cnt].nxt = head[u];
head[u] = cnt;
indegree[v]++; // 入度加1(实际上在无向图中建2次边,相当于是总度数而不是入度)
}
int quickMi(int x, int y){
int ans = 1, res=x;
while(y){
if(y&1) ans = ans*res;
res*= res;
y>>=1;
}
return ans;
}
// 遍历从x引出的子树的结点个数
int DFS(int x){
if(vis[x]) return 0;
vis[x] = true;
int sum = 1;
for(int i=head[x]; i; i=edge[i].nxt)
sum+=DFS(edge[i].to);
// 当查到叶节点的时候,to相当于该叶节点的父亲结点,利用vis数组直接返回0
return sum;
}
int main()
{
scanf("%d", &n);
int u, v;
For(i, 1, n-1){
scanf("%d%d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
For(i, 1, n){
if(indegree[i]==1) continue; // 总度数是1---说明是叶节点
memset(vis, 0, sizeof vis);
memset(f, 0, sizeof f);
memset(size1, 0, sizeof size1);
printf("The root i is: %d\n", i);
vis[i] = true;
int tot = 0;
// 遍历根节点的各个子树,计算各个子树的结点数量
for(int j = head[i]; j; j = edge[j].nxt){
int to = edge[j].to;
if(vis[to]) continue;
size1[++tot] = DFS(to);
}
f[0] = 1;
For(i, 1, tot) printf("它的第%d棵子树有%d个结点\n", i, size1[i]);
/* 这里这个|=看不懂 */
for(int j = 1; j<=tot; j++){
for(int k= n; k>=size1[j]; k--){
f[k]|=f[k-size1[j]];
ans[k]|=f[k];
}
}
}
For(i, 1, n-2){
if(!ans[i]) continue;
ans1++;
}
cout<<ans1<<endl;
For(i, 1, n-2){
if(!ans[i]) continue;
cout<<i<<" "<<n-1-i<<endl;
}
return 0;
}
然后有问题的就是注释中提到的那个区域
CPP/* 这里这个|=看不懂 */
for(int j = 1; j<=tot; j++){
for(int k= n; k>=size1[j]; k--){
f[k]|=f[k-size1[j]];
ans[k]|=f[k];
}
}
希望得到大佬解答QAQ
回复
共 4 条回复,欢迎继续交流。
正在加载回复...