14223: 【原4223】枯萎的树
题目
题目描述
author: zms 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/4223
Description
从前有棵树。一棵有n个节点的树(节点标号1~n)。现在树上有一些边枯萎了。为了救活这棵树,zwx希望在树上某些节点滴加营养液,使得从该节点到根节点的所有枯萎的边恢复正常。根节点的编号默认为1。众所周知,滴加营养液数较少的方案一定更优。在此基础上,营养液流经边数较少的方案较优。现在希望你找到一个最优的方案,输出最少的营养液滴数以及其作用节点(按节点标号从小到大排列)。
Input Format
第一行一个整数n。接下来n-1行每行3个整数,i,j,k,为节点i与j之间有一条边,k=1正常,k=2枯萎。
Output Format
第一行一个整数表示营养液滴数x,第二行x个整数表示作用节点。
Sample Input
5
1 2 2
1 3 2
1 4 2
1 5 2
Sample Output
4
2 3 4 5
Limit
对于\(40%\)的数据,\(n \leq 10^4\)
对于\(100%\)的数据,\(n \leq 10^5\)
ligongzzz's solution
#include <iostream>
#include <vector>
using namespace std;
class node {
public:
int parent = 0;
vector<int> child;
vector<int> isbad;
bool good = false;
};
int n;
vector<node> tdata;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
tdata.resize(n + 1);
for (int a = 0; a < n; ++a) {
int i, j, k;
cin >> i >> j >> k;
tdata[i].child.emplace_back(j);
tdata[j].child.emplace_back(i);
}
return 0;
}
zqy2018's solution
#include <bits/stdc++.h>
#define INF 2000000000
using namespace std;
typedef long long ll;
int read(){
int f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
return f * x;
}
int n;
int to[200005], at[100005] = {0}, nxt[200005], cnt = 0, id[200005] = {0}, tot = 0;
bool used[100005] = {0};
bool dfs(int cur, int fa){
bool ans = false;
for (int i = at[cur]; i; i = nxt[i]){
if(to[i] == fa) continue;
bool res = dfs(to[i], cur);
if(id[i] == 2){
if(!res) used[to[i]] = ans = true, tot++;
else ans = true;
}else{
if(res) ans = true;
}
}
return ans;
}
void init(){
n = read();
for (int i = 1; i < n; ++i){
int u = read(), v = read(), st = read();
to[++cnt] = v, nxt[cnt] = at[u], id[cnt] = st, at[u] = cnt;
to[++cnt] = u, nxt[cnt] = at[v], id[cnt] = st, at[v] = cnt;
}
}
void solve(){
dfs(1, 0);
printf("%d\n", tot);
for (int i = 1; i <= n; ++i)
if(used[i]) printf("%d ", i);
}
int main(){
init();
solve();
return 0;
}