1015: [JSOI2008]星球大战starwar

题目: http://www.lydsy.com/JudgeOnline/problem.php?id=1015 

倒着做,变成插入点和边维护强连通分量,用并查集。
注意星球编号是从0~n-1
#include <iostream>
#include 
<cstdlib>
#include 
<cstdio>
#include 
<cstring>
using namespace std;
const int MaxM=300500;
const int MaxK=600500;

int n,m,k,a[MaxM][2],b[MaxK],father[MaxK],ans=0;
bool vis[MaxK],v[MaxK];
int head[MaxK],next[2*MaxM],node[2*MaxM],t=0;
int aans[MaxK];

void add(int x,int y)
{
    node[t]
=y;
    next[t]
=head[x];
    head[x]
=t;
    t
++;
    node[t]
=x;
    next[t]
=head[y];
    head[y]
=t;
    t
++;
}


int findfather(int x)
{
    
if (father[x]==x)
    
{
        
return x;
    }

    
return father[x]=findfather(father[x]);
}


bool bing(int x,int y)
{
    
int fx=findfather(x),fy=findfather(y);
    
if (fx==fy) return 0;
    father[fx]
=fy;
    
return 1;
}


void init()
{
    memset(next,
-1,sizeof(next));
    memset(head,
-1,sizeof(head));
    scanf(
"%d%d",&n,&m);
    
for (int i=0;i<n;i++)
    
{
        vis[i]
=0;
        father[i]
=i;
        v[i]
=0;
    }

    
for (int i=0;i<m;i++)
    
{
        scanf(
"%d%d",&a[i][0],&a[i][1]);
        add(a[i][
0],a[i][1]);
    }

    scanf(
"%d",&k);
    
for (int i=0;i<k;i++)
    
{
        scanf(
"%d",&b[i]);
        vis[b[i]]
=1;
    }

}


void treat()
{
    for (int i=0;i<n;i++)
    
{
        
if (vis[i]==1continue;
        ans
++;
        
for (int j=head[i];j!=-1;j=next[j])
        
{
            
if (vis[node[j]]==0)
            
{
                
if (bing(node[j],i)==1)
                
{
                    ans
--;
                }

            }

        }

    }

}


int main()
{
    init();
    treat();
    aans[k]=ans;
    
for (int i=k-1;i>=0;i--)
    
{
        vis[b[i]]
=0;
        ans
++;
        
for (int j=head[b[i]];j!=-1;j=next[j])
        
{
            
if (vis[node[j]]==0)
            
{
                
if (bing(node[j],b[i])==1)
                
{
                    ans
--;
                }

            }

        }

        aans[i]
=ans;
    }

    
for (int i=0;i<=k;i++)
    
{
        printf(
"%d\n",aans[i]);
    }

    
return 0;
}


posted on 2013-01-17 11:11 Kiro 阅读(138) 评论(0)  编辑 收藏 引用 所属分类: 衡八oj