PAT-1013 Battle Over Cities (25)

求解连通性问题,最好用的当然是并查集了,可以使用深搜或者广搜。

这道题目的意思是给定一些道路,如果把其中一个顶点去掉,那么需要建立多少条道路才能联通所有顶点。

这道题目如果用朴素的并查集的话第四个测试用例会超时,因此想到带路径压缩的并查集。递归或者非递归方式都可以,对于这道题目来说不会差别很大,不过用递归可能会有栈溢出的问题,当数据量小的时候没有什么大问题。(其实递归的深度不会很大,所以RE得风险应该很小的,已建立起来的数目只有两层。错误,比如两个帮派老大带了一群小弟,一个帮派老大投靠了另外一个小弟,那么就会出现三层的情况,并不是说并查集就是一定是两层的,可能会有多个两层合在一起,那么就出现三层了)

#include<stdio.h>
#include<stdlib.h>

#define MAX 1010

struct Edge
{
   int a;
   int b;
}edge[MAX*MAX];

int father[MAX];

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

void output(int n)
{
    for(int i=1;i<=n;i++)
       printf("%d ",father[i]);
}

int findFather(int x)
{
    while(x!=father[x])
       x=father[x];
    return x;
}
int findFatherWithCompress(int x)//4    答案正确    119     4216    4/4  递归寻找父亲节点,然后把节点挂载到父亲节点上
{
    if(x!=father[x])
      father[x]=findFatherWithCompress(father[x]);
    return father[x];
}

int findFatherWithCompress2(int x)//开始先找到x的父亲节点,此时并未压缩,然后沿着x-->father[x]一直压缩路径,把节点直接赋值给最顶层的父亲节点
{
    int r=x;
    while(r!=father[r])
        r=father[r];
    int k=x;
    while(father[k]!=r)
    {
      int j=father[k];//j exchange for father[k]
      father[k]=r;
      k=j;
     }
     return r;
}
void merge(int a,int b)
{
   int x=findFatherWithCompress2(a);
   int y=findFatherWithCompress2(b);
   if(x!=y)
     father[x]=y; //find father and merger them
}
int main()
{
    int n,m,k;
    freopen("1013-in.txt","r",stdin);
    freopen("1013-out.txt","w",stdout);

    while(scanf("%d%d%d",&n,&m,&k)!=EOF)
    {

    for(int i=0;i<m;i++)
      scanf("%d%d",&edge[i].a,&edge[i].b);

    for(int j=0;j<k;j++)
    {
       init(n);
       int c,a,b;
       scanf("%d",&c);
       for(int i=0;i<m;i++)
       {
          a=edge[i].a;
          b=edge[i].b;
          if(a==c||b==c)
             continue;
          merge(a,b);
       }
       int count=0;
       //output(n);
       for(int i=1;i<=n;i++)
       {
          if(father[i]==i)
          {
             count++;
          }
       }
       printf("%d\n",count-2);//except the city
    }

   }
    return 0;
} 
时间: 2024-12-27 21:09:53

PAT-1013 Battle Over Cities (25)的相关文章

1013. Battle Over Cities (25)——PAT (Advanced Level) Practise

题目信息: 1013. Battle Over Cities (25) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue 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 th

PAT Advanced Level 1013 Battle Over Cities (25)(25 分)

1013 Battle Over Cities (25)(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

PAT 甲级 1013 Battle Over Cities (25 分)(图的遍历,统计强连通分量个数,bfs,一遍就ac啦)

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 oth

1013 Battle Over Cities (25分) DFS | 并查集

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 othe

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

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 othe

PAT Advanced 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

PAT:1013. Battle Over Cities (25) AC

#include<stdio.h> #include<string.h> #include<vector> using namespace std; const int MAX=1010; int n,m,k; //城市数,高速公路数,查询次数 int DELETE; //要删除的点 vector<int> ADJ[MAX]; //邻接表 bool vis[MAX]; void DFS(int s) { if(DELETE==s) return; //表示该

PAT (Advanced Level) 1013. Battle Over Cities (25)

并查集判断连通性. #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<map> using namespace std; const int maxn=1010; struct Edge { int u,v; }e[maxn*maxn]; int n,m,k; int f[maxn]; i

PAT甲题题解-1013. Battle Over Cities (25)-求联通分支个数

题目就是求联通分支个数删除一个点,剩下联通分支个数为cnt,那么需要建立cnt-1边才能把这cnt个联通分支个数求出来怎么求联通分支个数呢可以用并查集,但并查集的话复杂度是O(m*logn*k)我这里用的是dfs,dfs的复杂度只要O((m+n)*k)这里k是指因为有k个点要查询,每个都要求一下删除后的联通分支数.题目没给定m的范围,所以如果m很大的话,dfs时间会比较小. for一遍1~n个点,每次从一个未标记的点u开始dfs,标记该dfs中访问过的点.u未标记过,说明之前dfs的时候没访问过

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