解決策:都市がキャプチャされるたびに、都市のすべての近隣を削除し、lost [city] == trueで都市が占領されたことを示し、ListComponents()関数で接続されたコンポーネントの数を計算しますいつこの街をスキップします。したがって、都市の削除後の接続されたコンポーネントの数が削除前の接続されたコンポーネントの数よりも多い場合、それは都市がハブであることを意味し、そうでない場合は通常の都市です。
エラーが発生しやすいポイント:1。ListComponents()関数を実行するたびに、vis []配列をfalseにリセットする必要があります。2. K == Nの場合、最後にゲームオーバーを出力します。
補足:無向グラフで接続されたセットの数をカウントするには、2つの方法があります。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;
}