1.P5908 猫猫和企鹅 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
啊啊啊啊啊啊啊啊啊啊啊啊o(* ̄▽ ̄*)ブ第一次自己做对dfs加二叉树的题啊啊啊啊啊啊啊啊啊啊,emmmm虽然是之前遇到过类似的kkk
#include
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
vectorve[N];
#define int long long
int dis[N], d, cn = 0;
void dfs(int x, int fa) {
for (auto i : ve[x]) {
if (i == fa)
continue;
dis[i] = dis[x] + 1;
if (dis[i] <= d)
cn++;
dfs(i, x);
}
}
void solve() {
int n, u, v;
cin >> n >> d;
for (int i = 1; i < n; i++) {
cin >> u >> v;
ve[u].push_back(v);
ve[v].push_back(u);
}
dfs(1, 0);
cout << cn;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
2.P1395 会议 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
//5555超时了,70/100,但起码有思路了,感觉emmm好像这种题都一个思路
#include
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
vectorve[N];
#define int long long
int dis[N];
int cn = 0;
void dfs(int x, int fa) {
for (auto i : ve[x]) {
if (i == fa)
continue;
dis[i] = dis[x] + 1;
cn += dis[i];
dfs(i, x);
}
}
void solve() {
int n, u, v;
cin >> n;
for (int i = 1; i < n; i++) {
cin >> u >> v;
ve[u].push_back(v);
ve[v].push_back(u);
}
int mi = inf, flag;
for (int i = 1; i <= n; i++) {
cn = 0;
memset(dis, 0, sizeof dis);
//fill(dis + 1, dis + n + 1, 0);
dfs(i, 0);
if (mi > cn) {
mi = cn;
flag = i;
}
//cout << cn << endl;
}
cout << flag << ' ' << mi;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
之后画图推了一下,发现假设有这样一颗树:
1——2——4
|
3
易知:1:0+1+2+2=5,2:1+0+1+1=3,3:2+1+0+2=5,4:2+1+2+0=5
再多推几棵树,不难发现,a[2]=a[1]+4-2*3,a[3]=a[2]+4-2*1,a[4]=a[2]+4-2*1
所以就是:a[x]=a[y]+n-2*(x的子节点)=5+4-2*3
所以就求出1的路径和之后推下面的就好了,就不用再用memset或fill之类的,节省时间
kk,虽然思路清楚,但对于我这个菜鸟还是不会写,然后去看了题解
主要:1:用邻接表存数,什么是邻接表捏,就是一种图的存储方式,,,具体,,,暂时不知道,,
2:dfs遍历求f[1],但看某佬的代码,,,没用dfs,就是跟下面的一样的方法,然后本来想两个结合的,,,,小生不才,,
3:就是求上面的那个x的子节点
#include
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
#define int long long
int n, hason[N], f[N], yy = 1;
int u, v;
//邻接表
int tot, la[N * 2], to[N * 2], h[N];
void hsb(int x, int y) {
to[++tot] = y;
la[tot] = h[x];
h[x] = tot;
}
//邻接表
int hsc(int x, int y) {
for (int i = h[x]; i; i = la[i])
if (to[i] != y)
hason[x] += 1 + hsc(to[i], x);
return hason[x];
}
void hsa(int x, int y) {
f[x] = f[y] - (hason[x] + 1) + (n - hason[x] - 1);
for (int i = h[x]; i; i = la[i])
if (to[i] != y)
hsa(to[i], x);
}
void hsd(int x, int y, int z) {
f[1] += z;
for (int i = h[x]; i; i = la[i])
if (to[i] != y)
hsd(to[i], x, z + 1);
}
void solve() {
cin >> n;
for (int i = 1; i < n; i++) {
cin >> u >> v;
hsb(u, v), hsb(v, u);
}
hsc(1, 0);
for (int i = h[1]; i; i = la[i])
hsd(to[i], 1, 1);
for (int i = h[1]; i; i = la[i])
hsa(to[i], 1);
for (int i = 2; i <= n; i++)
if (f[i] < f[yy])
yy = i;
cout << yy << ' ' << f[yy];
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
总的就是一直递归,递归,,,,,,,呜呜呜呜呜呜,,,好难,,,,4h,,真晕,,算了,70也不少了╥﹏╥...,,,现在的我确实配不上这道题,,,,,