codeforces 216 DIV C. Valera and Elections

原创 2013年12月04日 14:21:53


C. Valera and Elections
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

The city Valera lives in is going to hold elections to the city Parliament.

The city has n districts and n - 1 bidirectional roads. We know that from any district there is a path along the roads to any other district. Let's enumerate all districts in some way by integers from 1 to n, inclusive. Furthermore, for each road the residents decided if it is the problem road or not. A problem road is a road that needs to be repaired.

There are n candidates running the elections. Let's enumerate all candidates in some way by integers from 1 to n, inclusive. If the candidate number i will be elected in the city Parliament, he will perform exactly one promise — to repair all problem roads on the way from the i-th district to the district 1, where the city Parliament is located.

Help Valera and determine the subset of candidates such that if all candidates from the subset will be elected to the city Parliament, all problem roads in the city will be repaired. If there are several such subsets, you should choose the subset consisting of the minimum number of candidates.

Input

The first line contains a single integer n (2 ≤ n ≤ 105) — the number of districts in the city.

Then n - 1 lines follow. Each line contains the description of a city road as three positive integers xiyiti (1 ≤ xi, yi ≤ n1 ≤ ti ≤ 2) — the districts connected by the i-th bidirectional road and the road type. If ti equals to one, then the i-th road isn't the problem road; if tiequals to two, then the i-th road is the problem road.

It's guaranteed that the graph structure of the city is a tree.

Output

In the first line print a single non-negative number k — the minimum size of the required subset of candidates. Then on the second line print k space-separated integers a1, a2, ... ak — the numbers of the candidates that form the required subset. If there are multiple solutions, you are allowed to print any of them.

Sample test(s)
input
5
1 2 2
2 3 2
3 4 2
4 5 2
output
1
5 
input
5
1 2 1
2 3 2
2 4 1
4 5 1
output
1
3 
input
5
1 2 2
1 3 2
1 4 2
1 5 2

output
4
5 4 3 2 

这题用自己常用的map【】【】肯定不行啊,因为有10^5个点,10^5条边,其实以前月神就问过我碰到这样的情况怎么办,当时我不知道的说。他是指针控,这题他是用链表记录的,我和他不一样,我看我们数据结构书上说了稀疏矩阵的三元组表存储,所以这道我就用上了。

这题用dfs就行了,不断往下早,直到遍历完所有的点就行了,具体怎么做,还是看代码吧,我说不清楚。(自己的渣渣的表达能力实在是我自己都受不了自己)


代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<limits.h>
using namespace std;
struct node
{
	int be;
	int end;
	int v;
}list[211111];  //以三元组表的形式记录图 
int hash[211111];//记录以第i点为起点的边的数目 
int ans[211111];//记录改点是否需要输出 
int sum[211111];//以前i个点为起点的边的数目,方便查找 
int vis[211111];// 记录第i个点前面以vis[i]为起点道路的需要修理 
int hehe[211111];// 判断该点是否已经遍历了,如果已经遍历过,则不需要再遍历(因为图为n点,n-1条边) 
int cmp(node x,node y)
{
	return x.be < y.be;
}
void dfs(int t)
{
	if(hash[t]==0)
		return;
	for(int i= 1,j= sum[t-1]+1; i<= hash[t]; i++,j++)
	{
		if(hehe[list[j].end])
			continue;
		hehe[list[j].end]= hehe[list[j].be] +1;
		if(list[j].v==1)
		{
			ans[list[j].end]= 0;
			vis[list[j].end]= vis[list[j].be];
			dfs(list[j].end);
			// 如果该边不需要修理,则 记录之前需要修理的边		
		}
		else
		{
			ans[list[j].end]= 1;
			ans[list[j].be]= 0;
			ans[vis[list[j].be]]= 0;
			vis[list[j].be]= 0;
			vis[list[j].end]= list[j].end;
			dfs(list[j].end);
			// 如果该边需要修理,则list[j].end之前的边都会随之修理,
			// 所以 	ans[vis[list[j].be]]= 0; 代表将之前需要的边删除
			// 例如 4个点(编号1,2,3,4),点1和点2之间的边需要修理,23之间不需要,34之间需要
			// 遍历第一条边的时候,ans【2】= 1,vis【2】= 2;
			// 遍历第二条边的时候,vis【3】= vis【2】= 2; 表示前三个点中,点2之前有边需要修理, 
			// 那么遍历到第三条边的时候,ans【2】 应该变为0,
			//同时vis【4】= 4,表示点4之前有边需要修理,点2之前没有边需要修理
			 
		}
	}	
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		memset(ans,0,sizeof(ans));
		memset(vis,0,sizeof(vis));
		memset(hash,0,sizeof(hash));
		memset(sum,0,sizeof(sum));
		memset(hehe,0,sizeof(hehe));
		for(int i= 1; i< n; i++)
		{
			scanf("%d%d%d",&list[i].be,&list[i].end,&list[i].v);		
			hash[list[i].be]++;
			hash[list[i].end]++;
			list[n+i-1].be= list[i].end;
			list[n+i-1].end= list[i].be;
			list[n+i-1].v= list[i].v;//双向图,每条边记录两次 
		}
		sort(list+1,list+2*n-1,cmp);// 排序方便搜索的时候找到起点和终点	
		sum[0]= 0;
		for(int i=1; i<= n; i++)
			sum[i]=sum[i-1]+ hash[i]; //记录每个点的起点	
		hehe[1]= 1;		
		dfs(1);
		int anssum= 0;
		for(int i=1; i<= n; i++)
			if(ans[i])
				anssum++;
		printf("%d\n",anssum); 
		int flag= 0;
		for(int i= 1; i<= n; i++)
			if(ans[i])
			{
				if(flag==0)
				{
					printf("%d",i);
					flag= 1;
				}
				else
					printf(" %d",i);
			}
		if(anssum)			
			printf("\n");
	}
}



Codeforces Round #216 (Div. 2)---C. Valera and Elections

The city Valera lives in is going to hold elections to the city Parliament.The city has n districts ...

Codeforces Round #216 C Valera and Elections ( DFS )

题目链接:   C 题目大意:   给出N(N                   选择某个结点,从这个结点出发到达1结点的路都会被修复                   求这些结点的集...

Codeforces Round #216 (diy.2) C. Valera and Elections

题目链接:点击打开链接 题意:给一棵树,N-1条边的权值可以是1和2。要找包含权值为2的边的路径有几条,并            记录这条路径中距离点1最远的点。 分析: 就是树形dp,或者说是树上的...

CodeForces 369C. Valera and Elections

C. Valera and Elections time limit per test 1 second memory limit per test 256 megabytes...

Codeforces Round #216_div2_D.Valera and Fools

近些日子以来总觉得编程水平没怎么提升,这学期开始虽然每周有四场的队内训练赛,但几个月下来感觉收获不大。想想,还是以刷题的方式来学习吧。每天刷个一两题,然后写写题解。一味的打比赛打比赛被逼的很紧但是却没...

Codeforces 369C Valera and Elections【思维+Dfs】

C. Valera and Elections time limit per test 1 second memory limit per test 256 megabytes ...

Codeforces Round #216_div2_E.Valera and Queries

转载注明出处   http://blog.csdn.net/moedane     传送门 http://codeforces.com/contest/369/problem/E   题意 给出n条线...

Codeforces Round #216 (Div. 2) A. Valera and Plates

A. Valera and Plates time limit per test 1 second memory limit per test 256 megabytes ...

Codeforces Round #216 (Div. 2) E. Valera and Queries (树状数组)

题目地址:http://codeforces.com/contest/369/problem/E 看完题目,很明显是离散+树状数组的思路,然而并没有想到怎么离散。这题的解法实在巧妙。 这题要求的是...

Codeforces Round #252 (Div. 2) B. Valera and Fruits(模拟)

B. Valera and Fruits time limit per test 1 second memory limit per test 256 megabytes ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:codeforces 216 DIV C. Valera and Elections
举报原因:
原因补充:

(最多只允许输入30个字)