湖南多校对抗赛(2015.05.03)Problem B: War

并查集。从后往前加边。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn = 1000000 + 10;
int father[maxn], u[maxn], v[maxn], Q, q[maxn], ans[maxn], ff[maxn];
int find(int x)
{
    if (x != father[x]) father[x] = find(father[x]);
    return father[x];
}
int main()
{
    int n, m, i;
    while (~scanf("%d%d", &n, &m))
    {
        memset(ff, 0, sizeof(ff));
        for (i = 0; i <= n; i++) father[i] = i;
        for (i = 1; i <= m; i++) scanf("%d%d", &u[i], &v[i]);
        scanf("%d", &Q);
        for (i = 1; i <= Q; i++){ scanf("%d", &q[i]); ff[q[i]] = 1; }
        int tot = n;//没有边的时候有n个集合
        for (i = 1; i <= m; i++)
        {
            if (ff[i] == 0)
            {
                int uf, vf;
                uf = find(u[i]);
                vf = find(v[i]);
                if (vf != uf)
                {
                    father[vf] = uf;
                    tot--; //加入一条边,集合少一个
                }
            }
        }
        ans[1] = tot;
        int j = 2;
        for (i = Q; i > 1; i--)
        {
            int uf, vf;
            uf = find(u[q[i]]);
            vf = find(v[q[i]]);
            if (vf != uf)
            {
                father[vf] = uf;
                tot--; //加入一条边,集合少一个
            }
            ans[j] = tot; j++;
        }
        for (i = Q; i >= 1; i--)
        {
            if (i > 1) printf("%d ", ans[i]);
            else printf("%d\n", ans[i]);
        }
    }
    return 0;
}
时间: 2024-08-19 01:38:44

湖南多校对抗赛(2015.05.03)Problem B: War的相关文章

湖南多校对抗赛3.28 J - Jerry&#39;s trouble

Problem J: Jerry's trouble Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 96  Solved: 46 [Submit][Status][Web Board] Description Jerry is caught by Tom. He was penned up in one room with a door, which only can be opened by its code. The code is the

湖南多校对抗赛(2015.03.28) E Longest Increasing Subsequence Again

题意:给你一个序列,问你删除掉连续的一段,使得剩下的序列的最长上升字串最大,问你这个最大值. 解题思路:分段dp,  dp[i][0] ,dp[i][1]   , 0表示前面没有切过,只能从前一个数的0状态得到,1状态表示前面已经切过了,能从前一个的1状态得到,也能从 在他前面的比他值小的dp[j][0](j < i && a[j] < a[i])的最大值得到,这里用线段树维护就行了. 解题代码: 1 // File Name: b.cpp 2 // Author: darkd

湖南多校对抗赛(2015.03.28) G Good subsequence

题意:找到一个序列中极值<=k的最长字串的长度. 解题思路:set容器双递推. 解题代码: 1 // File Name: g.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 12时04分39秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque>

湖南多校对抗赛(2015.03.28) A Rectangle

题意:给你一些最多宽为2 的木板,让你放在一个宽为二的盒子里面,问你这个盒子最短有多长. 解题思路:DP,离中间最近的那个值. 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 12时13分56秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9

湖南多校对抗赛(2015.03.28) B Design road

题意:给你起点(0,0),终点(x,y),中间有很多条河, 在河上面建桥花费c1,在陆地建路花费c2,问你最小花费是多少. 解题思路:我们知道,我们考虑的时候完全可以把河都移动到一边来求,这样只需要三分就行了. 解题代码: 1 // File Name: b.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 13时26分39秒 4 5 #include<vector> 6 #include<list> 7 #

湖南多校对抗赛(2015.03.28) H SG Value

题意:给你一个集合,动态插入 ,动态询问,然后问你这个集合的sg值(这个集合用加法运算不能产生的那个最小正整数)是多少. 解题思路:假设我们现在的这个SG值是 x 1)现在插入集合里面一个数v   如果这个v > x ,那么显然  sg值x不变,  把v放进从小到大的优先队列中 2)如果这个 v <= x 那么sg值x肯定就会变成  x + v, 每更新一次 sg值,就去看优先队列top元素是否是 小于等于 x的 ,如果小于等于,其实就等于把这个top元素进行1操作,这样就不会错了. 解题代码

湖南多校对抗赛(2015.03.28) I Inversion Sequence

题意:给你一个序列a[i],代表 i这个数 在b数列中有多少个值在它前面且比它大,问你求B序列 解题思路:线段树的简单应用,找第几个空,类似二分. 解题代码: 1 // File Name: i.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月28日 星期六 12时56分11秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<

湖南多校对抗赛(2015.05.03)Problem A: Twenty-four point

给四个数 问能不能算出24点...我的方法比较烂...920ms 差点TLE.应该有更好的方法. #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; double a[5], ff[5], n; double rt[30][5], yy[5]; int sum; double get(double x, double y,

湖南多校对抗赛(2015.05.24)部分解题报告(CSU1628-1638)

比赛网址 A:简单题 AC代码: #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<queue> #include<algorithm> using namespace std; int a[105]; int main() { #ifndef ONLINE_JUDGE freope