1.P5908 猫猫和企鹅 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
啊啊啊啊啊啊啊啊啊啊啊啊o(* ̄▽ ̄*)ブ第一次自己做对dfs加二叉树的题啊啊啊啊啊啊啊啊啊啊,emmmm虽然是之前遇到过类似的kkk
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
vector<int>ve[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 <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
vector<int>ve[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 <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
#define int long longint 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也不少了╥﹏╥...,,,现在的我确实配不上这道题,,,,,