【2020年天梯赛校选赛】7-14 战争地图!(邻接矩阵版本)

【2020年天梯赛校选赛】7-14 战争地图!(邻接矩阵版本)

由于叛徒朱子明的出卖,导致独立团在赵家峪的团部驻军在团长李云龙大婚之日几乎全军覆没。
突出重围之后,李云龙决定集合所有驻扎在外的部队,使用重型武器意大利炮攻打平安县城!
消息从团部穿出之后到达各部驻地后,驻地长官会派出自己的通讯人员通知其他部队。但是一旦该驻地被攻陷,那么该驻地就无法收到命令,同理与该驻地有道路连通的驻地也无法收到命令!
现在,李云龙想知道假设一个驻地被攻陷,所有的驻地会被分为几个连通块!
为了简化问题,不要求计算每个连通块的具体信息,只要求输出连通块的数量即可!

输入格式:
第一行包含两个正整数N(N<=1000)和M(<=2000),表示整个战区一共有N个驻地,这N个驻地由M条无向小道相连!(驻地由1到N编号)
接下来M行,每行包含两个驻地编号,表示这两个驻地之间有一条小道相连!
接下来一行包含一个正整数q,表示有q个询问!
接下来q行,每行包含一个驻地编号!

输出格式:
对于每个询问,请你输出在删掉它和所有与它相连的小道之后,这个战区的驻地形成的连通块数量!
值得注意的一点是,每个询问相互独立!

输入样例:
在这里给出一组输入。例如:
8 8
1 2
1 4
2 3
4 3
3 5
5 7
5 6
5 8
3
3
5
7

输出样例:
在这里给出相应的输出。例如:
2
4
1

代码:

#include <iostream>					//7-9 战争地图!(邻接矩阵版本)
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
const int MaxV = 1002;	//最大顶点数

int N, M;			//输入顶点数与边数
bool Vis[MaxV];		//标记是否访问

/*邻接表需要的结构定义*/
typedef struct ENode{
	int v1, v2;
} * Edge;
struct AdjVNode{
	int AdjV;
	AdjVNode *Next;
};
typedef struct VNode{
	AdjVNode *FirstEdge;
} AdjList[MaxV];
typedef struct GNode{
	int Nv, Ne;
	AdjList L;
} * LGraph;

void InsertEdge(LGraph G, Edge E)		//插入无向边
{
	AdjVNode *A;
	A = new AdjVNode;
	A->AdjV = E->v1;
	A->Next = G->L[E->v2].FirstEdge;
	G->L[E->v2].FirstEdge = A;

	A = new AdjVNode;
	A->AdjV = E->v2;
	A->Next = G->L[E->v1].FirstEdge;
	G->L[E->v1].FirstEdge = A;
}

void DestroyGraph(LGraph G)				//释放内存
{
	AdjVNode *A;
	for (int i = 1; i <= G->Nv; i++)
		while (G->L[i].FirstEdge)
		{
			A = G->L[i].FirstEdge;
			G->L[i].FirstEdge = A->Next;
			delete A;
		}
	delete G;
}

int BFS(int k, LGraph G)		//用BFS统计连通分量个数
{
	int ans = 0;
	Vis[k] = true;
	queue<int> q;
	AdjVNode *A;

	for (int i = 1; i <= G->Nv; i++)
	{
		if(Vis[i])
			continue;
		q.push(i);
		while (!q.empty())		//应用BFS搜索
		{
			int k = q.front();
			q.pop();
			A = G->L[k].FirstEdge;
			while (A)
			{
				if(!Vis[A->AdjV])
					Vis[A->AdjV] = true, q.push(A->AdjV);
				A = A->Next;
			}
		}
		ans++;
	}
	return ans;
}

int main()
{
	int x, y;
	cin >> N >> M;
	LGraph G = new GNode();
	G->Nv = N, G->Ne = M;

	Edge E = new ENode;
	for (int i = 0; i < M; i++)
	{
		cin >> E->v1 >> E->v2;
		InsertEdge(G, E);
	}
	delete E;		//记得释放内存

	/*输入并测试*/
	int T, k;
	cin >> T;
	while (T--)
	{
		cin >> k;
		memset(Vis, false, sizeof(Vis));
		cout << BFS(k, G) << endl;
	}
	DestroyGraph(G);	//释放图的内存

	system("pause");
	return 0;
}

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页