HDU4496_D-City(并查集删边/逆向)

D-City

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 1315    Accepted Submission(s): 496

Problem Description

Luxer is a really bad guy. He destroys everything he met.

One day Luxer went to D-city. D-city has N D-points and M D-lines. Each D-line connects exactly two D-points. Luxer will destroy all the D-lines. The mayor of D-city wants to know how many connected blocks of D-city left after Luxer destroying the first K D-lines
in the input.

Two points are in the same connected blocks if and only if they connect to each other directly or indirectly.

Input

First line of the input contains two integers N and M.

Then following M lines each containing 2 space-separated integers u and v, which denotes an D-line.

Constraints:

0 < N <= 10000

0 < M <= 100000

0 <= u, v < N.

Output

Output M lines, the ith line is the answer after deleting the first i edges in the input.

Sample Input

5 10
0 1
1 2
1 3
1 4
0 2
2 3
0 4
0 3
3 4
2 4

Sample Output

1
1
1
2
2
2
2
3
4
5

Hint

The graph given in sample input is a complete graph, that each pair of vertex has an edge connecting them, so there‘s only 1 connected block at first.
The first 3 lines of output are 1s  because  after  deleting  the  first  3  edges  of  the  graph,  all  vertexes  still  connected together.
But after deleting the first 4 edges of the graph, vertex 1 will be disconnected with other vertex, and it became an independent connected block.
Continue deleting edges the disconnected blocks increased and finally it will became the number of vertex, so the last output should always be N.

Source

2013
ACM-ICPC吉林通化全国邀请赛——题目重现

解题报告

给定一个图,N个点,M条边,求按顺序删边后剩下的多少联通块。

一般我们都是用并查集来加边,删边也可以用并查集,删除第1条边等于加上m-1条边。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#define M 100000+10
#define N 10000+10
using namespace std;
int n,m;
struct node
{
    int u,v;
} edge[M];
int B[N],ans[M];
int fine(int x)
{
    if(B[x]!=x)
    B[x]=fine(B[x]);
    return B[x];
}
int main()
{
    int i;
    while(~scanf("%d%d",&n,&m))
    {
    memset(ans,0,sizeof(ans));
    memset(edge,0,sizeof(edge));
        for(i=0;i<n;i++)
        B[i]=i;
        for(i=0; i<m; i++)
        {
            scanf("%d%d",&edge[i].u,&edge[i].v);
        }
        int sum=n;
        for(i=m-1;i>=0;i--)
        {
            ans[i]=sum;
            int xx=fine(edge[i].u);
            int yy=fine(edge[i].v);
            if(xx!=yy)
            {
                sum--;
                B[xx]=yy;
            }
        }
        for(i=0;i<m;i++)
        printf("%d\n",ans[i]);
    }
    return 0;
}

HDU4496_D-City(并查集删边/逆向)

时间: 2024-10-19 08:54:49

HDU4496_D-City(并查集删边/逆向)的相关文章

ZOJ 3261 - Connections in Galaxy War ,并查集删边

In order to strengthen the defense ability, many stars in galaxy allied together and built many bidirectional tunnels to exchange messages. However, when the Galaxy War began, some tunnels were destroyed by the monsters from another dimension. Then m

南阳1022--合纵连横 (并查集+删点)

合纵连横 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 乱世天下,诸侯割据.每个诸侯王都有一片自己的领土.但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大.而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国. 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟.最开始,每个诸侯国是一个联盟. 有两种操作 1

UVA 11987 并查集删点

并查集删点就是弄个id记录当前点的id,删除的时候将id设为新的id,忽略原来的id,当然还要注意去改变原来集合需要维护的性质比如元素个数等等. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) m

hdu 3081 【二分匹配+并查集+删边||最大路+并查集+二分枚举】

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2307    Accepted Submission(s): 792 Problem Description Presumably, you all have known the question of stable marriage match. A

nyoj_1022:合纵连横(并查集删点)

http://acm.nyist.net/JudgeOnline/problem.php?pid=1022 只附代码好了 #include<bits/stdc++.h> using namespace std; const int N=200005; int a[N],b[N],vis[N]; int n,m,add,kase; void init() { for(int i=0;i<n;i++) a[i]=i,b[i]=i; add=n; memset(vis,0,sizeof(vis

ZOJ - 3261 Connections in Galaxy War(并查集删边)

https://cn.vjudge.net/problem/ZOJ-3261 题意 银河系各大星球之间有不同的能量值, 并且他们之间互相有通道连接起来,可以用来传递信息,这样一旦有星球被怪兽攻击,便可通过通道找到能量值最大的星球来帮忙.但是有一些通道被怪兽破坏了. 现在先给出原来的所有通道, 然后进行询问,询问有两种方式: destroy a b: 连接a,b的通道被怪兽破坏了 query a: 询问a能否通过通道找到救兵,只能找能量值比自己大的救兵. 分析 逆向思维,先离线存储所有的输入操作,

Connections in Galaxy War ZOJ - 3261 离线操作+逆序并查集 并查集删边

#include<iostream> #include<cstring> #include<stdio.h> #include<map> #include<vector> #define cle(a) memset(a,0,sizeof(a)) using namespace std; const int N=50000+10; int w[20100]; bool cmp(int a,int b){ return a>b; } int n

BZOJ 3319 黑白树 并查集+线段树

这这这这这这什么毒瘤题!!!!!!!!!!!!!!!!!!!!!!!!!!!! 卡LCT(优秀的LCT由于是均摊本身就带着2,3的常数在,而且这道题对于LCT标记十分难维护,又得乘上4,5然后就炸了),卡树剖,卡正解,但是暴力能A!!!!!!!!!!!!!!!!!!!!!! 所谓正解就是线段树为护dfs序+并查集删点去重,这东西在每个点一秒的时候都过不了Po姐都虚. 但是我在网上看到一个大佬有一个神思路A掉了 下面是我改过之后的的TLE程序 #include<cstdio> #include&

并查集练习1

举头望明月,低头敲代码... 推荐学习地址:http://www.cnblogs.com/cyjb/p/UnionFindSets.html 简单: hdu1213 How Many Tables:新手必秒 1 #include<cstdio> 2 const int N=1001; 3 int f[N]; 4 void init(int n){ 5 for(int i=1;i<=n;++i) 6 f[i]=i; 7 } 8 int fin(int x){ 9 if(x!=f[x])f[