bzoj1015[JSOI2008]星球大战starwar

来源:互联网 发布:c4d r18 mac 注册机 编辑:程序博客网 时间:2024/04/29 02:50

分析:思路比较明显了,直接并查集,正着做不行倒着呗,直接倒着做,变成一个个加点,这样就和谐很多了。

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;typedef long long ll;const int N=5e5+5;int n,m;int head[N],go[N],next[N];bool vis[N],bz[N];int tot,d,fa[N],q[N],ans[N],cnt=1;int find(int x){    if (x==fa[x])return fa[x];    else return fa[x]=find(fa[x]);}inline void ins(int x,int y){    go[++cnt]=y;    next[cnt]=head[x];    head[x]=cnt;}inline void add(int x){    int i=head[x],p=find(x),q;    while (i)    {        int v=go[i];        if (vis[v])        {            q=find(v);            if (p!=q)            {                fa[q]=p;                tot--;            }        }        i=next[i];    }}int main(){    scanf("%d%d",&n,&m);    fo(i,0,n-1)fa[i]=i;    fo(i,1,m)    {        int x,y;        scanf("%d%d",&x,&y);        ins(x,y);        ins(y,x);    }    scanf("%d",&d);    fo(i,1,d)    {        scanf("%d",&q[i]);        bz[q[i]]=1;    }    fo(i,0,n-1)    {        if (!bz[i])        {            ++tot;            add(i);            vis[i]=1;        }    }    ans[d+1]=tot;    fd(i,d,1)    {        tot++;        add(q[i]);        vis[q[i]]=1;        ans[i]=tot;    }    fo(i,1,d+1)printf("%d\n",ans[i]);    return 0;}
0 0
原创粉丝点击