cf #216 C - Valera and Elections
题目大意:给你一棵树,节点间的边有的有标记1,有的有标记2,问你至少选取哪几个节点使得这些节点到节点1的路径中包含了所有的标记为2的边;
思路:统计每个节点下与标记为2的边相邻的节点的数目,选取的节点即为数目为1的节点编号;
代码:
#include<iostream> #include<algorithm> #include<cmath> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<queue> #include<deque> //#define DEBUG //todo using namespace std; int nn; struct node{ int to; node *next; }*head[110000],*tail[110000]; int ans[110000],f[110000]; int n,x,y,t,cnt; void ini() { cnt=0; memset(ans,0,sizeof(ans)); memset(head,NULL,sizeof(head)); memset(tail,NULL,sizeof(tail)); cin>>n; node *temp; int tmp; for(int i=1;i<n;i++){ cin>>x>>y>>t; if(t==2) f[x]=f[y]=1; temp=new node; if(head[x]==NULL) { head[x]=tail[x]=temp; } else { tail[x]->next=temp; tail[x]=temp; } temp->to=y; temp->next=NULL; temp=new node; if(head[y]==NULL) { head[y]=tail[y]=temp; } else { tail[y]->next=temp; tail[y]=temp; } temp->to=x; temp->next=NULL; } } void calc(int i,int pre) { if(f[i]) ans[i]++; if(head[i]==NULL) { return; } node *temp=head[i]; while(temp){ if(temp->to==pre) {temp=temp->next; continue;} calc(temp->to,i); ans[i]+=ans[temp->to]; temp=temp->next; } } void work() { calc(1,-1); for(int i=2;i<=n;i++) { if(ans[i]==1) cnt++; } cout<<cnt<<endl; if(cnt!=0) for(int i=2;i<=n;i++) { if(ans[i]==1 && cnt!=1) { cout<<i<<" "; cnt--; } else if(ans[i]==1 && cnt==1) cout<<i<<endl; } } int main() { ini(); work(); #ifdef DEBUG cin>>nn; #endif return 0; }
对于这个题目,我只想说,你的代码写得跟xiang一样!!!