程序设计课 期末考试复习 专题五:树形结构

前言:由于时间真不多了。。。之后的专题都会是题目加代码,可能会有一点分析。。。我真的复习不完了~~~

第五个专题:树形结构

并查集和最小生成树的算法:kruskal。比较重要的两个算法。

有关题目:CSP 2018-12-T4。

首先要抓住这几个要素:无向图、有边权、求最小生成树。

这题本意就是要求最小生成树中最大的边。

首先说一下kruskal的执行过程:适用于无向图,首先从图中选取最小的边权,放入到一个集合中,从原图去掉该边。接下来一直从图中取最小边权的边,但有一个条件,取出来的边不能够成环路,如果构成环路,那么要去掉这条边从再从图中找。直到集合中所有的边构成了一个无环路的树,这棵树就是最小生成树。

而最大边就是最后一次取出来的。

代码:

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

#define MAX 100005
struct edge
{
	int x, y;
	int w;
}e[MAX];
int fa[MAX];
int ans;
int cmp(edge a, edge b)//排序函数
{
	if (a.w != b.w)
		return a.w<b.w;
	else
	{
		return a.x<b.x;
	}
}
void make_set(int x)//初始化节点
{
	fa[x] = x;
}
int find(int x)//查找父节点
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

void union_set(int x, int y, int w)//合并节点
{
	fa[y]=x;
	if (ans<w)
	{
		ans = w;
	}
}
int main()
{
	int x, y, w;
	int m, n, root;//n是点,m是边
	cin >> n >> m >> root;
	for (int i = 0; i<m; i++)
	{
		cin >> x >> y >> w;
		e[i].x = x;
		e[i].y = y;
		e[i].w = w;
		make_set(x);
		make_set(y);
	}
	sort(e, e + m, cmp);
	ans = 0;
	for (int i = 0; i<m; i++)
	{
		x = find(e[i].x);
		y = find(e[i].y);
		w = e[i].w;
		if (x != y)
		{
			union_set(x, y, w);
		}
	}
	cout << ans << endl;
	return 0;
}

这份代码是靠“点”来判断是否构成了图的回路。

本章还接着CSP的题目布置了CSP 2018-12-T2的作业,一并附上代码。

题目:

问题描述

  一次放学的时候,小明已经规划好了自己回家的路线,并且能够预测经过各个路段的时间。同时,小明通过学校里安装的“智慧光明”终端,看到了出发时刻路上经过的所有红绿灯的指示状态。请帮忙计算小明此次回家所需要的时间。

输入格式

  输入的第一行包含空格分隔的三个正整数 r、y、g,表示红绿灯的设置。这三个数均不超过 10^6。

  输入的第二行包含一个正整数 n,表示小明总共经过的道路段数和路过的红绿灯数目。

  接下来的 n 行,每行包含空格分隔的两个整数 k、t。k=0 表示经过了一段道路,将会耗时 t 秒,此处 t 不超过 10^6;k=1、2、3 时,分别表示出发时刻,此处的红绿灯状态是红灯、黄灯、绿灯,且倒计时显示牌上显示的数字是 t,此处 t 分别不会超过 r、y、g。

输出格式

  输出一个数字,表示此次小明放学回家所用的时间。

题解:就是一个按照红绿灯顺序,建立了一个长的时间序列,判断时间进行时,所到路口的红绿灯情况。每过一个路口就增加一定的时间。

注意红绿灯顺序是:黄灯、红灯、绿灯

代码:

#include<iostream>
using namespace std;
int r,y,g;
int tim(int x)
{
	if(x>y+r) return 0;
	else return y+r-x;
}

int main()
{
	//int r,y,g;
	cin>>r>>y>>g;
	int n;
	cin>>n;
	int k,t;
	long long sum=0;
	while(n--)
	{
		cin>>k>>t;
		if(k==0) sum+=t;
		else if(k==1) sum+=tim((y+r-t+sum)%(y+r+g));
		else if(k==2) sum+=tim((y-t+sum)%(y+r+g));
		else sum+=tim((y+r+g-t+sum)%(y+r+g));
	}
	cout<<sum<<endl;
	return 0;
}

 

发布了6 篇原创文章 · 获赞 0 · 访问量 184

猜你喜欢

转载自blog.csdn.net/morning_zs202/article/details/92802859