【树】【习题汇总】

之前紫书的树学的比较乱,只顾着做题。现在从新学一下树这种数据结构。

poj1330

练习一下用双亲数组存储树,和遍历树。

这个题只要一条路走到根位置,把走过的位置标记就行,然后判断另一条是否经过这个点。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int maxn=10000+10;
int a[maxn];
int t,n;
bool vis[maxn];
int main()
{
	//freopen("in.txt","r",stdin);
	cin>>t;
	while(t--)
	{
		int x,y;
		cin>>n;
		memset(a,0,sizeof(a));
		memset(vis,false,sizeof(vis));
		for(int i=0;i<n-1;++i)
		{
			cin>>x>>y;
			a[y]=x;
		}
		cin>>x>>y;
		while(y!=0)
		{
			vis[y]=true;
			y=a[y];
		}
		while(!vis[x])
			{x=a[x];}
		cout<<x<<endl;
	}
	return 0;
}

poj2499

思路:因为二叉树到所有节点的路径是唯一的,所以我们可以从节点出发,依次向着根走。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int t,kase=0;

int main()
{
	cin>>t;
	while(t--)
	{
		int a,b,right=0,left=0;
		cin>>a>>b;
		int temp;
		while(a!=1||b!=1)//这里是或
		{
			if(a>b)
			{
				temp=(a-1)/b;//数据规模较大,一次减除来,因为根节点是(1,1)所以a-1,下面同理。
				a-=(b*temp);
				left+=temp;
			}else 
			{
				temp=(b-1)/a;
				b-=a*temp;
				right+=temp;
			}
		}
		printf("Scenario #%d:\n%d %d\n\n",++kase,left,right);
	}
	return 0;
}

poj2255

二叉树的遍历

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

char a[30],b[30];
int L1,R1,L2,R2;
vector<char>ans;
void tree(int L1,int R1,int L2,int R2)
{
	if(L1>R1)return ;
	int k=0;
	while(a[L1]!=b[L2+k])k++;
	tree(L1+1,L1+k,L2,L2+k-1);
	tree(L1+k+1,R1,L2+k+1,R2);
	ans.push_back(a[L1]);
}
int main()
{
	//freopen("in.txt","r",stdin);
	while(cin>>a>>b)
	{
		ans.clear();
		L1=strlen(a);
		tree(0,L1-1,0,L1-1);
		for(int i=0;i<ans.size();++i)
			cout<<ans[i];
		cout<<endl;
	}
	return 0;
}

poj2309

思路:注意观察图中树的特点。

1如果x为奇数,则是单独节点。

2如果x为偶数,则最底层的数字在[x-2^k+1,x-1][x+1,x+2^k-1]。其中2^k可以用x&(-x)计算出来,涉及到负数的二进制表示。

#include <iostream>
#include <cstdio>
using namespace std;
int t,x,k;
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>x;
		k=x&(-x);
		cout<<x-k+1<<" "<<x+k-1<<endl;
	}
	return 0;
}

zoj2724

二叉堆,根节点小于(大于)叶节点,采用优先队列。注意结构体和strcmp的使用

数据量比较大,建议改成scanf和printf.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;

struct message
{
	char name[100];
	int data;
	int priority;
	bool operator <(const message &a) const
	{
		return a.priority<priority;
	}
};

priority_queue<message>q;
char cmd[100];
message m;

int main()
{
	//freopen("in.txt","r",stdin);
	while(scanf("%s",&cmd)!=EOF)
	{
		if(strcmp(cmd,"GET")==0)
		{
			if(!q.size())cout<<"EMPTY QUEUE!\n";
			else 
			{
				cout<<q.top().name<<" "<<q.top().data<<endl;
				q.pop();
			}
		}
		else if(strcmp(cmd,"PUT")==0)
		{
			cin>>m.name>>m.data>>m.priority;
			q.push(m);
		}
	}
	return 0;
}

poj3253

哈夫曼树 权值*路径之和最低 此处采用优先队列。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

priority_queue<int,vector<int>,greater<int> >q;

int main()
{
	int n,temp;
	while(cin>>n)
	{
		while(!q.empty())q.pop();
		for(int i=0;i<n;++i)
		{
			cin>>temp;
			q.push(temp);
		}
		int a,b;
		long long ans=0;
		while(q.size()>1)
		{
			a=q.top();q.pop();
			b=q.top();q.pop();
			ans+=(a+b);
			q.push(a+b);
		}
		cout<<ans<<endl;
	}
	return 0;
}
发布了22 篇原创文章 · 获赞 3 · 访问量 1834

猜你喜欢

转载自blog.csdn.net/qq_42825058/article/details/87897938