题目大意:给你一颗树,如果某个节点连接着偶数条边,那么这个点就可以被删除,同时它所连接的边也被删除,问是否可以吧整课树完全删除。
大概思路:首先,n位偶数肯定不行,因为题目保证有n-1条边,而每次都会删偶数条,最后至少会剩一条。然后就是从最下面往上搜,先判断子节点是否满足条件,如果满足就删掉,删除之后,它的所有子节点都可以删,因为,它的子节点如果留了下来,那么边数是奇数,删除与父节点所连接的那条边后,所剩边数一定是偶数。
代码
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 using namespace std; 5 vector <int > zz[200005]; 6 vector <int > sb; 7 int aa[200005],t=-1; 8 int bfss (int x) 9 { 10 if (aa[x]) return 0; 11 aa[x]=1; 12 sb.push_back(x); 13 for (int j=0;j<zz[x].size();j++) 14 bfss(zz[x][j]); 15 return 0; 16 } 17 void bfs (int x) 18 { 19 int s=0; 20 if (x!=t) s++; 21 for (int j=0;j<zz[x].size();j++) 22 { 23 bfs(zz[x][j]); 24 if (!aa[zz[x][j]]) s++; 25 } 26 if (s%2==0) bfss(x); 27 return ; 28 } 29 int main () 30 { 31 //freopen ("data.in","r",stdin); 32 int n,a; 33 cin >>n; 34 for (int j=1;j<=n;j++) 35 { 36 cin >>a; 37 if (!a) 38 { 39 t=j; 40 continue; 41 } 42 zz[a].push_back(j); 43 } 44 bfs(t); 45 if(sb.size()!=n) 46 { 47 cout<<"NO"<<endl; 48 return 0; 49 } 50 cout <<"YES"<<endl; 51 for (vector <int > ::iterator i=sb.begin();i!=sb.end();i++) 52 cout <<*i<<endl; 53 return 0; 54 }
刚开始想着记录所有有偶数条边的节点然后直接删下去,但是如果像下面这种情况,就会先删除7,6,8,然后4-5就会变成一条孤立的线,但是按照8,10,4,5,7,1,3,9,11,2,6就可以完全删除
11
7 11 7 6 4 11 0 4 3 8 3