程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 3562: [SHOI2014]神奇化合物 並查集+dfs

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

編輯:C++入門知識

點擊打開鏈接

注意到20w條邊,但是詢問只有1w,所以有很多邊是從頭到尾不變的。

首先離線處理,將從未刪除的邊縮點,縮點後的圖的點數不會超過2w,對於每一次add或者delete,直接dfs看是否能從a走到b,然後維護一個ans。

數據不強,不然這種復雜度起碼要跑10s。。

 

#include
#include
#include
#include
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;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved