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一样!!!

posted on 2013-12-01 15:37  uestc小田  阅读(230)  评论(0编辑  收藏  举报

导航