L2-013. 红色警报->并查集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SelinaFelton/article/details/79750586

磨叽了两年终于愿意写了的题目。。。
其实这个题也不难,就是略微有点麻烦,可以采用并查集判断一个城市被攻占前后图的连通块有多少个,需要注意的是,如果某个城市没有和任何城市连通,则其被攻占后无影响。我的做法是通过合并操作后,在统计连通区域的时候顺带统计每个连通块里的城市个数,如果某个被攻占的城市恰好在被攻占前所在连通区域只有它一个城市,则单独处理。
GPLT里L2的题目其实思想也都很基础,千万别往难想,坑自己

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int n , m;
#define MAX 505
int Map[MAX][MAX];
int p[MAX];
int visit[MAX];
int deliii[MAX];
int Find(int x)
{
    int temp = p[x];
    while(temp != p[temp])
    {
        temp = p[temp];
    }
    return temp;
}
void join(int x, int y)
{
    int tx = Find(x);
    int ty = Find(y);
    if(tx < ty)
        p[ty] = tx;
    else
        p[tx] = ty;
}
void init()
{
    for(int i = 0 ; i <MAX  ; i ++)
        p[i] = i;
}
void merge_map()
{
    for(int i = 0 ; i < n ; i ++)
    {
        for(int j = 0 ; j < n ; j ++)
        {
            if(Map[i][j]==1)
                join(i,j);
        }
    }
    for(int i = 0 ; i < n ; i ++)
    {
        if(!deliii[i])
        {
            visit[Find(i)]++;
            //cout << Find(i) << "&&&&"<<i<<endl;
        }

    }
}
void del(int ttt)
{
    for(int i = 0 ; i < n ; i ++)
    {
        Map[i][ttt] = 0;
        Map[ttt][i] = 0;
    }
}
int main()
{
    memset(Map, 0 , sizeof(Map));
    memset(deliii, 0 , sizeof(deliii));
    scanf("%d%d", &n,&m);
    int a, b ;
    init();
    for(int i = 0 ; i < m ; i ++)
    {
        scanf("%d%d", &a, &b);
        Map[a][b] = 1;
    }
    int k , ttt;
    scanf("%d", &k);
    memset(visit, 0, sizeof(visit));
    merge_map();
    int city = 0, nowcity = 0;
    for(int i = 0 ; i < n ; i ++)
    {
        if(visit[i]) city ++;
    }
    int flagv ;
    for(int i = 0 ; i < k ; i ++)
    {
        flagv = 0;
        scanf("%d", &ttt);
        if(visit[ttt] == 1) flagv = 1;
        deliii[ttt] = 1;
        del(ttt);
        init();
        memset(visit, 0, sizeof(visit));
        merge_map();
        for(int j = 0 ; j < n ; j ++)
            if(visit[j] > 0) nowcity++;
        //cout << city << "***"<<ttt<< "***"<<nowcity<<endl;
        if(nowcity == 0) printf("City %d is lost.\nGame Over.\n",ttt);
        else if(city == nowcity||(flagv == 1))
            printf("City %d is lost.\n",ttt);
        else
            printf("Red Alert: City %d is lost!\n", ttt);
        city = nowcity;
        nowcity = 0;
    }
    return 0;
}
阅读更多
换一批

没有更多推荐了,返回首页