首页 > 其他 > 详细

BZOJ 3562: [SHOI2014]神奇化合物 并查集+dfs

时间:2014-06-14 12:07:51      阅读:377      评论:0      收藏:0      [点我收藏+]

点击打开链接

注意到20w条边,但是询问只有1w,所以有很多边是从头到尾不变的。

首先离线处理,将从未删除的边缩点,缩点后的图的点数不会超过2w,对于每一次add或者delete,直接dfs看是否能从a走到b,然后维护一个ans。

数据不强,不然这种复杂度起码要跑10s。。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 5001
#define M 530005
struct node2
{
    char q;
    int a,b;
}f[200005],Q[10005];
struct node
{
    int v,next;
}edge[M];
int head[N],set[N];
bool d[N][N],v[N];
int e[N][N];
int id,ans;
void add(int a,int b)
{
    edge[id].v=b;
    edge[id].next=head[a];
    head[a]=id++;
}
void init(int n)
{
    memset(head,-1,sizeof(head));
    id=ans=0;
	for(int i=1;i<=n;i++)set[i]=i;
}
int find(int x)
{
    if(x!=set[x]) return set[x]=find(set[x]);
    return set[x];
}
void merge(int x,int y)
{
	set[find(y)]=find(x);
}

bool dfs(int a,int b)
{
    if(a==b) return true;
    for(int i=head[a];~i;i=edge[i].next)
    {
        int to=edge[i].v;
        if(e[a][to]>0&&!v[to])
        {
            v[to]=true;
            if(dfs(to,b)) return true;
        }
    }
    return false;
}
int n;
void addedge(int a,int b)
{
    memset(v,false,sizeof(v));
    if(!dfs(a,b)) ans--;
    e[a][b]++;
    e[b][a]++;
    add(a,b);
    add(b,a);
}
void del(int a,int b)
{
    memset(v,false,sizeof(v));
    e[a][b]--;
    e[b][a]--;
    if(!dfs(a,b)) ans++;
}
inline int ReadInt()
{
    char ch = getchar();
    int data = 0;
    while (ch < '0' || ch > '9')
    {
        ch = getchar();
    }
    do
    {
        data = data*10 + ch-'0';
        ch = getchar();
    }while (ch >= '0' && ch <= '9');
        return data;
}
int main()
{
    int m,a,b,q;
    n=ReadInt();
    m=ReadInt();
    init(n);
    for(int i=1;i<=m;i++)
    {
        f[i].a=ReadInt();
        f[i].b=ReadInt();
    }
    q=ReadInt();
    for(int i=1;i<=q;i++)
    {
        scanf("%s",&Q[i].q);
        if(Q[i].q!='Q')
        {
            Q[i].a=ReadInt();
            Q[i].b=ReadInt();
            if(Q[i].q=='D') d[Q[i].a][Q[i].b]=d[Q[i].b][Q[i].a]=true;
        }
    }
    for(int i=1;i<=m;i++)
    {
        if(!d[f[i].a][f[i].b]) merge(f[i].a,f[i].b);
    }
    for(int i=1;i<=n;i++)
    {
        if((set[i]=find(i))==i) ans++;
    }
    for(int i=1;i<=m;i++)
    {
        if(set[f[i].a]!=set[f[i].b]) addedge(set[f[i].a],set[f[i].b]);
    }
    for(int i=1;i<=q;i++)
    {
        if(Q[i].q=='Q') printf("%d\n",ans);
        else if(Q[i].q=='D') del(set[Q[i].a],set[Q[i].b]);
        else addedge(set[Q[i].a],set[Q[i].b]);
    }
    return 0;
}


BZOJ 3562: [SHOI2014]神奇化合物 并查集+dfs,布布扣,bubuko.com

BZOJ 3562: [SHOI2014]神奇化合物 并查集+dfs

原文:http://blog.csdn.net/t1019256391/article/details/30573197

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!