zoukankan      html  css  js  c++  java
  • BZOJ 1015 星球大战 并查集+离线

       这道题说来真是艰辛,从一开始的RE,到RE,到刚刚的WA,再到AC。 这只能说明我进步的历程,还有我需要不断的加强努力。这道题思路不难,从很久前在黑书中并查集一节就能找到解题的踪影,因为并查集只能并,分不了,所以我们就得离线,倒过来写。只不过这道题真的得审好题目,它问的是剩下的星球中有多少个连通分量,不要搞错了。大概就是这个样子了,加油。

     1 #include<cstdio>
     2 #include<iostream>
     3 #define rep(i,j,k) for(int i= j; i <=k; i++)
     4 #define down(i,j,k) for(int i = j; i >= k; i--)
     5 #define maxn 200005
     6 using namespace std;
     7 
     8 int read()
     9 {
    10     int s = 0, t = 1; char c = getchar();
    11     while( !isdigit(c) ){
    12         if( c == '-' ) t = -1; c = getchar();
    13     }
    14     while( isdigit(c) ){
    15         s = s * 10 + c - '0'; c = getchar();
    16     }
    17     return s * t;
    18 }
    19 
    20 int fa[maxn],rank[maxn];
    21 int find(int x)
    22 {
    23     return x == fa[x] ? x : fa[x] = find(fa[x]);
    24 }
    25 
    26 int bing(int x,int y)
    27 {
    28     if( rank[x] > rank[y] ) fa[y] = x;
    29     else fa[x] = y;
    30 }
    31 
    32 struct edge{
    33 int to; edge* next;
    34 };
    35 edge *head[maxn*2], *pt, edges[maxn*2];
    36 
    37 void add_edge(int x,int y)
    38 {
    39     pt->to = x, pt->next = head[y], head[y] = pt++;
    40     pt->to = y, pt->next = head[x], head[x] = pt++;
    41 }
    42 
    43 int q[maxn*2]; bool used[maxn*2] = {0};
    44 int ans[maxn*2];
    45 
    46 int main()
    47 {
    48     pt = edges; int n = read(), m = read();
    49     rep(i,1,n+1) fa[i] = i;  
    50     rep(i,1,m){
    51         int u = read(), v = read();
    52         add_edge(u,v);
    53     }
    54     int k = read();
    55     rep(i,1,k){
    56         q[i] = read();
    57         used[q[i]] = 1;
    58     }
    59     int tot = 0;
    60     rep(i,0,n-1){
    61         if( !used[i] ){
    62             tot++;
    63             for(edge*e = head[i]; e; e=e->next){
    64                 int to = e->to;
    65                 if( !used[to] ){
    66                     int x = find(i), y = find(to);
    67                     if( x != y ){
    68                         bing(x,y);
    69                         tot--;
    70                     }
    71                 }
    72             }
    73         }
    74     }
    75     ans[k+1] = tot;
    76     down(i,k,1){
    77         int x = q[i];
    78         used[x] = 0; tot++;
    79         for(edge*e = head[x]; e; e=e->next){
    80             int to = e->to;
    81             if( !used[to] ){
    82                 int xx = find(x), xy = find(to);
    83                 if( xx != xy ){
    84                     bing(xx,xy); tot--; 
    85                 }
    86             }
    87         }
    88         ans[i] = tot;
    89     }
    90     rep(i,1,k+1) printf("%d
    ", ans[i]);
    91     return 0;
    92 }
  • 相关阅读:
    (一)jQuery EasyUI 的EasyLoader载入原理
    java playframework
    android Handlerr.removeCallbacksAndMessages(null)的妙用
    云已成为一种趋势,大有可为
    将一个4X4的数组进行逆时针旋转90度后输出,要求原数组数据随机输入
    小强的HTML5移动开发之路(40)——jqMobi中实践header定义的几种方式
    AngularJS中的依赖注入
    极光消息推送服务器端开发实现推送(下)
    用CSS指定外部链接的样式
    版本控制(1)——SVN
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5092797.html
Copyright © 2011-2022 走看看