题意:现在有n个候选人, 有n-1条路, 如果选择了这个候选人, 这个候选人就会将从自己这个城市到1号城市上所有坏的路都修复一下,现在求最小的候选人数目, 如果答案有多种情况输出任何一种都可以。
输入:x y k 表示x与y之间有一条双向通道, k==1 表示这路是好的, k == 2表示这条路是坏的。
题解: 从1开始dfs搜索, 往外走, 如果遇到坏的城市就标记一下, 然后继续往外走, 如果更远的地方有一个坏的路就用更远地方的城市候选人代替这个标记的这个人。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define fi first 4 #define se second 5 typedef pair<int, int> pll; 6 const int INF = 0x3f3f3f3f; 7 const int N = 1e5+5; 8 vector<pll> E[N]; 9 bool vis[N]; 10 int cnt = 0; 11 void dfs(int x, int n, int last) 12 { 13 for(int i = 0; i < E[x].size(); i++) 14 { 15 pll tmp = E[x][i]; 16 if(tmp.fi == last) continue; 17 if(tmp.se == 2) 18 { 19 cnt++; 20 if(vis[n]) cnt--, vis[n] = 0; 21 vis[tmp.fi] = 1; 22 dfs(tmp.fi, tmp.fi, x); 23 } 24 else dfs(tmp.fi, n, x); 25 } 26 } 27 int main() 28 { 29 int n; 30 scanf("%d",&n); 31 int x, y, ok; 32 for(int i = 1; i < n; i++) 33 { 34 scanf("%d%d%d",&x,&y,&ok); 35 E[x].push_back(pll(y,ok)); 36 E[y].push_back(pll(x,ok)); 37 } 38 memset(vis, 0, sizeof(vis)); 39 dfs(1,0,0); 40 printf("%d ", cnt); 41 for(int i = 2; i <= n; i++) 42 if(vis[i]) printf("%d ",i); 43 return 0; 44 }