进阶实验6-3.1 红色警报 (25 分)

解决思路:每当一个城市被攻占以后,把这个城市的所有的邻边都删掉,并且lost[city]==true来表示该城市已经被占领,在ListComponents()函数中计算连通分量个数时就跳过这个city。从而,如果删除city后的连通分量的个数大于删除前的连通分量个数,说明该城市是一个枢纽否则是一个普通城市。

易错点:1、每次在执行ListComponents()函数时,一定要把vis[]数组重置为false。2、当K==N时,在最后输出Game Over!

补充:统计无向图中连通集个数有两种方法:1、用并查集 。2、图的遍历。我的解法是图的DFS

下面是代码:

#include<stdio.h>
#define MAXV 505
#define INF 65535
#include<algorithm>
using namespace std;
int n,G[MAXV][MAXV];
bool lost[MAXV]= {false};
bool vis[MAXV] = { false };
void DFS(int v)
{
	int w;
	vis[v] = true;
	for(w=0; w<n; w++)
		if(vis[w]==false&&G[v][w]==1)
			DFS(w);
}
int ListComponents()
{
	int v; int count = 0;
	for(v=0; v<n; v++)
	{
		if(vis[v]==false&&lost[v]==false) //对于被占领的城市直接跳过
		{
			count++;
			DFS(v);
		}
	}
	return count;
}
int main()
{
	int i,j; int v;
	int N,M,K; int v1,v2;
	scanf("%d %d",&N,&M);
	n = N;
	for(i=0; i<n; i++)
		for(j=0; j<n; j++)
			G[i][j] = INF;
	for(i=0; i<M; i++)
	{
		scanf("%d %d",&v1,&v2);
		G[v1][v2] = 1;
		G[v2][v1] = 1;
	}
	scanf("%d",&K);
	int city;int start,end;
	for(i=0; i<K; i++)
	{
		scanf("%d",&city);
		lost[city] = true;
		fill(vis,vis+n,false);
		start = ListComponents(); 
		for(v=0; v<n; v++)//切断city与其他城市的联系
		{
			if(G[city][v]!=INF)
			{
				G[city][v] = INF;
				G[v][city] = INF;
			}
		}
		fill(vis,vis+n,false);
		end = ListComponents(); 
		if(start == end)
			printf("City %d is lost.\n",city);
		else if(start < end)
			printf("Red Alert: City %d is lost!\n",city);
	}
	if(K==N)	
	{printf("Game Over.\n");}
	return 0;
}






 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值