zoukankan      html  css  js  c++  java
  • 洛谷 P1197 [JSOI2008]星球大战

    题目传送门

    解题思路:

    并查集,逆序做(即先假设给的k个星球全都被炸,求出此时的联通块个数,就是经过k次打击的联通块个数。然后再加上最后一个被炸的星球,就求出了经过k-1次打击的联通块个数。。。以此类推,最后把所有点都加进去,就求出了经过0次打击后连同块个数)

    //转载自:https://www.luogu.org/blog/user25199/solution-p1197

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<bits/stdc++.h>
     4 
     5 using namespace std;
     6 
     7 int n,m,fa[400001],tot,br[400001],sum[400002],head[400001],k;
     8 struct kkk {
     9     int from,next,to;
    10 }g[400001];
    11 bool vis[400001];
    12 
    13 void add(int a,int b) {
    14     g[++tot].from = a;
    15     g[tot].to = b;
    16     g[tot].next = head[a];
    17     head[a] = tot; 
    18 }
    19 
    20 int find_father(int x) {
    21     if(fa[x] == x) return x;
    22     return fa[x] = find_father(fa[x]);
    23 }
    24 
    25 void merge(int x,int y) {
    26     int x1 = find_father(x);
    27     int y1 = find_father(y);
    28     fa[y1] = x1;
    29 }
    30 
    31 int main() {
    32     scanf("%d%d",&n,&m);
    33     for(int i = 0;i <= n; i++) {
    34         fa[i] = i;
    35         head[i] = -1;
    36     }
    37     for(int i = 1;i <= m; i++) {
    38         int x,y;
    39         scanf("%d%d",&x,&y);
    40         add(x,y);
    41         add(y,x);
    42     }
    43     scanf("%d",&k);
    44     for(int i = 1;i <= k; i++) {
    45         scanf("%d",&br[i]);
    46         vis[br[i]] = 1;
    47     }
    48     int ans = n - k;
    49     for(int i = 1;i <= 2 * m; i++) {
    50         if(!vis[g[i].from] && !vis[g[i].to] && find_father(g[i].from) != find_father(g[i].to)){
    51             ans--;
    52             merge(g[i].from,g[i].to);
    53         }        
    54     }
    55     sum[k+1] = ans;
    56     for(int i = k;i >= 1; i--) {
    57         ans++;
    58         vis[br[i]] = 0;
    59         for(int j = head[br[i]];j != -1;j = g[j].next) {
    60             if(!vis[g[j].to] && find_father(br[i]) != find_father(g[j].to)) {
    61                 ans--;
    62                 merge(br[i],g[j].to);
    63             }
    64         }
    65         sum[i] = ans;
    66     }
    67     for(int i = 1;i <= k + 1; i++)
    68         printf("%d
    ",sum[i]);
    69     return 0;
    70 }
  • 相关阅读:
    iOS 面试题 1
    ios 面试题 0
    得到程序包路径
    UISwitch 监听响应
    在[self addsubView:xxx]中,self.name 和 _name的区别
    /调整button的title的位置
    //设置导航条背景图片
    警告框
    @synthesize
    打开控制台选中路径的文件夹
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11241188.html
Copyright © 2011-2022 走看看