zoukankan      html  css  js  c++  java
  • 【BZOJ 1015】 [JSOI2008]星球大战starwar

    【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1015

    【题意】

    【题解】

    /*
        可以倒过来考虑;
        相当于一个加入了一个节点;
        然后问你联通块的数量;
        可以记录所有节点有哪些边和它是连在一起的;
        然后查询新加入的节点的边的另外一端是哪些节点;
        之后的操作会让这些节点连起来;
        看看边的另外一端的点对应的不同联通块有多少个->x;
        有多少个联通块就减去x-1;
        (具体实现的时候,先让这个新加入的节点和相邻的点尝试连起来,如果
        它们之前是不连通的那么计数器num递增,然后联通块的个数now=now+1-num);
        用并查集吧。
        (一开始联通块的个数为n-k哦)
    */


    【完整代码】

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <map>
    using namespace std;
    #define rei(x) scanf("%d",&x)
    #define rep2(i,y,x) for (int i = y;i >= x;i--)
    #define rep1(i,x,y) for (int i = x;i <= y;i++)
    
    const int N = 4e5 + 1000;
    const int M = 2e5 + 1000;
    
    struct abc
    {
        int x, y;
    };
    
    int n, m,ans[N],now;
    int f[N],k,a[N];
    bool bo[N];
    vector <int> g[N];
    abc bian[M];
    
    int ff(int x)
    {
        if (f[x] == x) return x;
        else
            return f[x] = ff(f[x]);
    }
    
    int main()
    {
        //freopen("D:\rush.txt", "r", stdin);
        //freopen("D:\rush_out.txt", "w", stdout);
        rei(n),rei(m);
        rep1(i, 1, m)
        {
            int x, y;
            rei(x), rei(y);
            g[x].push_back(y),g[y].push_back(x);
            bian[i].x = x, bian[i].y = y;
        }
        memset(bo, true, sizeof bo);
        rei(k);
        rep1(i, 1, k)
        {
            rei(a[i]);
            bo[a[i]] = false;
        }
        rep1(i, 0, n-1)
            f[i] = i;
        now = n-k;
        rep1(i, 1, m)
        {
            int x, y;
            x = bian[i].x, y = bian[i].y;
            if (!bo[x] || !bo[y]) continue;
            int r1 = ff(x), r2 = ff(y);
            if (r1 != r2)
            {
                f[r1] = r2;
                now--;
            }
        }
        rep2(i, k, 1)
        {
            ans[i] = now;
            int x = a[i],num = 0;
            bo[x] = true;
            int len = g[x].size();
            now++;
            rep1(j, 0, len - 1)
            {
                int y = g[x][j];
                if (!bo[y]) continue;
                int r1 = ff(y),r2 = ff(x);
                if (r1 != r2)
                {
                    f[r1] = r2;
                    num++;
                }
            }
            now -= num;
        }
        ans[0] = now;
        rep1(i, 0, k)
            printf("%d
    ", ans[i]);
        return 0;
    }
  • 相关阅读:
    阿里巴巴2018秋招面经之前端岗(1~5面)
    面试分享:2018阿里巴巴前端面试总结(题目+答案 30题)
    2018年各大互联网前端面试题三(阿里)
    阿里巴巴2016前端工程师面试题
    2016 阿里校招笔试前端题目,你还记得吗?
    2018阿里前端校招分享(笔试篇)
    2017 阿里校招前端笔试题小结
    阿里2018校招编程题
    ko.js学习一
    简单的3d变换
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626584.html
Copyright © 2011-2022 走看看