PAT 甲级刷题实录——1013

本贴最后更新于 1545 天前,其中的信息可能已经事过境迁

原题链接

思路

题目大意是说一些城市之间有路相通,假设其中一个城市被敌方占领了,计算需要新修多少条路才能让剩下的城市全部联通。首先这是一个典型的图论问题,我们可以用邻接矩阵去存城市之间的联通关系。可以用深度遍历的思想去解决这个问题。思路大意如下:建立一个数组存储哪些城市已经被联通,1 代表已联通,0 代表未联通;定义一个变量记录需要新修的路的数量,该变量初值为-1。对所有结点进行 for 循环遍历,遍历到一个结点时,如果该节点还未联通,则需要新修的路的数量加 1,并对该结点进行深度遍历以更新联通数组。变量初值为-1 而不是 0 的原因是因为这个算法记录了和被攻占城市联通的一条路,需要去除掉该路。

代码

#include <iostream>
#include <vector>
using namespace std;
void updateReached(int start);
vector<int> reached;
vector<int> cWay;
vector<vector<int> > ways;
int main()
{
	int N, M, K;
	cin >> N >> M >> K;
	cWay.assign(N + 1, 0);
	ways.assign(N + 1, cWay);
	vector<int> result;
	for (int i = 0; i < M; i++)
	{
		int c1, c2;
		scanf("%d %d",&c1,&c2);
		ways[c1][c2] = 1;
		ways[c2][c1] = 1;
	}
	for (int i = 0; i < K; i++)
	{
		int newWayNum = -1;
		reached.assign(N + 1, 0);
		int checked;
		scanf("%d",&checked);
		reached[checked] = 1;
		for (int j = 1; j < N+1; j++)
		{
			if (reached[j] == 0)
			{
				updateReached(j);
				newWayNum++;
			}
		}
		printf("%d\n",newWayNum);
	}
}
void updateReached(int start)	//更新start可达的城市到reach列表
{
	reached[start] = 1;
	for (int i = 1; i < reached.size(); i++)
	{
		if (ways[start][i] == 1 && reached[i] == 0)	//有路通且还没加入reached列表
		{
			updateReached(i);
		}
	}
	return;
}

这道题很坑的一点是一开始最后一个测试点一直运行超时,我还以为是算法逻辑出问题了,一直在找哪里有问题,找了半天找不出来。后来上网一查发现不少人都有运行超时的问题,原因是因为用了 C++ 风格的输入输出方式 cin 和 cout,这种输入输出方式的效率比 scanf 和 printf 低。解决方法就是改成 scanf 和 printf

  • PAT
    25 引用 • 1 回帖 • 1 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    106 引用 • 152 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...