这道题我做过类似的,但是还是不太会做,真是太菜了
(个人感觉牛客的每日一题挺好,我好多不会的,hhh)
其实这题也不会,看的别的大佬的思路写的,树形DP,感觉很好(最小割的话还是不会的,过段时间去学习下)
4 | 4 | 1 |
---|---|---|
1 | 2 | 1 |
2 | 3 | 1 |
2 | 4 | 1 |
这种情况我们切除 1 - 2 就可以,所以我们需要 += 去判断最小值。
然后dfs去搜索,标记好他的当前节点和父节点即可,然后求出f[s] 的最小值。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100010, M = 200010, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], d[N], w[M], f[N], idx;
int n, m, s;
void add(int x, int y, int z){
e[idx] = y, w[idx] = z, ne[idx] = h[x], h[x] = idx ++;
}
void dfs(int u, int p){
if (d[u] == 1 && u != s){
f[u] = INF;
return ;
}
for (int i = h[u]; i != -1; i = ne[i]){
int j = e[i];
if (j != p){
dfs(j, u);
f[u] += min(f[j], w[i]);
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&s);
memset(h, -1, sizeof h);
for (int i = 0; i < m; i++){
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
add(x, y, z), add(y, x, z);
d[x]++, d[y]++;
}
dfs(s,0);
printf("%d\n",f[s]);
return 0;
}