(甲)1013 Battle Over Cities (25 分)(并查集)

题目:

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.

For example, if we have 3 cities and 2 highways connecting city​1​​-city​2​​ and city​1​​-city​3​​. Then if city​1​​ is occupied by the enemy, we must have 1 highway repaired, that is the highway city​2​​-city​3​​.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.

Output Specification:

For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.

Sample Input:

3 2 3
1 2
1 3
1 2 3

Sample Output:

1
0
0

题意:

给你三个数字n,m,k,分别代表有n个城市,后面有m行,每一行都是两个数值aa和bb,代表城市aa和bb之间有一条路,后面又有一行,k个数字,代表编号为k的城市被占领,那么所有和城市k相连接的道路都要断开。问你把断开道路后的所有的城市连接起来要修多少条道路?

 

思路:

这道题你仔细看看就可以发现就是让你判断图的连通性的,那么直接用并查集就可以处理这一道题了。

但是需要注意最后结果的处理,并查集后可以知道现在的图分成了几块,但是有一块肯定是被占领的那一个城市,所以结果记得减去这一块,还有,两块地图联通只需要修建一条道路。综上所述,结果=图的块数-2;

代码如下:

#include
#include
#include
using namespace std;

const int N=1010;

int f[N];//存储boos;
int c;
int n,m,k;
vector >a;//存储城市之间的连接;

int getf(int v)//递归查找boos;
{
    if(f[v]==v)
        return v;
    else
        return f[v]=getf(f[v]);
}

void merge(int u,int v)//合并;
{
    int t1=getf(u);
    int t2=getf(v);
    if(t1!=t2)//boos节点不同就合并;
    {
        f[t2]=t1;
    }
}

void init()//初始化;
{
    for(int i=1; i<=n; i++)
    {
        f[i]=i;//自己的boos是自己;
    }
}

int pan(int x)
{
    int sum=0;
    for(int i=0; i

错误代码:

 不晓得怎么了,用数组存储城市之间的联通就是段错误,怎么改都不可以。。。。。用vector就可以了。。。。。

(甲)1013 Battle Over Cities (25 分)(并查集)_第1张图片

#include
#include
#include
using namespace std;

const int N=1010;

int f[N];
int a[N],b[N],c;
int n,m,k;

int getf(int v)
{
    if(f[v]==v)
        return v;
    else
        return f[v]=getf(f[v]);
}

void merge(int u,int v)
{
    int t1=getf(u);
    int t2=getf(v);
    if(t1!=t2)
    {
        f[t2]=t1;
    }
}

void init()
{
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
    }
}

int pan(int x)
{
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        if(a[i]!=x&&b[i]!=x)
            merge(a[i],b[i]);
    }
    for(int i=1;i<=n;i++)
    {
        if(f[i]==i)
            sum++;
    }
    return sum-2;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&a[i],&b[i]);
        }
        for(int i=1; i<=k; i++)
        {
            scanf("%d",&c);
            init();
            int sum=pan(c);
            printf("%d\n",sum);
        }
    }
    return 0;
}

当时可能脑子坏了,竟然忘记了数据的范围。。。。。。

还是要细心啊!

正确代码:

#include
#include
#include
using namespace std;
 
const int N=1010;
const int M=1000100;
int f[N];
int a[M],b[M],c;
int n,m,k;
 
int getf(int v)
{
    if(f[v]==v)
        return v;
    else
        return f[v]=getf(f[v]);
}
 
void merge(int u,int v)
{
    int t1=getf(u);
    int t2=getf(v);
    if(t1!=t2)
    {
        f[t2]=t1;
    }
}
 
void init()
{
    for(int i=1;i<=n;i++)
    {
        f[i]=i;
    }
}
 
int pan(int x)
{
    int sum=0;
    for(int i=1;i<=m;i++)
    {
        if(a[i]!=x&&b[i]!=x)
            merge(a[i],b[i]);
    }
    for(int i=1;i<=n;i++)
    {
        if(f[i]==i)
            sum++;
    }
    return sum-2;
}
 
int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&a[i],&b[i]);
        }
        for(int i=1; i<=k; i++)
        {
            scanf("%d",&c);
            init();
            int sum=pan(c);
            printf("%d\n",sum);
        }
    }
    return 0;
}

(甲)1013 Battle Over Cities (25 分)(并查集)_第2张图片

你可能感兴趣的:(PAT(甲),并查集)