求助 TLE只有30分

P1197 [JSOI2008] 星球大战

DiDi123 @ 2022-11-09 21:06:54

#include <bits/stdc++.h>
using namespace std;
#define MAXN 400010
int n,m,k;
int att[MAXN],fa[MAXN],ans[MAXN],buk[MAXN];
struct edge
{
    int to,nex;
}Edge[MAXN];
int head[MAXN],cnt;
void add(int u,int v)
{
    Edge[cnt].to=v;
    Edge[cnt].nex=head[u];
    head[u]=cnt++;
}
int sn[MAXN],sb[MAXN];
pair<int,int> rec[MAXN];
int getfather(int x)
{
    if(fa[x]==x) return x;
    fa[x]=getfather(fa[x]);
    return fa[x];
}
queue <int> q;
int vis[MAXN];
void bfs(int st)
{
    while(q.size()) q.pop();
    q.push(st);
    int t1,t2;
    while(q.size())
    {
        int tp=q.front();
        q.pop();
        if(vis[tp]) continue;
        vis[tp]=1;
        t1=getfather(tp);
        for(int i=head[tp];i>0;i=Edge[i].nex)
        {
            t2=getfather(Edge[i].to);
            if(t1!=t2) fa[t1]=t2;
            q.push(Edge[i].to);
        }

    }
}
inline int read()
{
    int x=0;
    char ch=getchar();
    while(ch>'9' || ch<'0') ch=getchar();
    while(ch>='0' && ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x;
}
int main()
{
    //  freopen("data.in","r",stdin);
    //  freopen("data.out","w",stdout);
    memset(head,-1,sizeof(head));
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<m;i++)
        sn[i]=i+1;
    for(int i=2;i<=m;i++)
        sb[i]=i-1;
    for(int i=1;i<=m;i++)
    {
        rec[i].first=read(),rec[i].second=read();
        rec[i].first++,rec[i].second++;
    }
    k=read();
    for(int i=1;i<=k;i++)
    {
        att[i]=read();
        att[i]++;
        buk[att[i]]=1;
    }
    int se=1;
    for(int i=1;i<=m;i++)
        if((!buk[rec[i].first]) && (!buk[rec[i].second])) //加完后就删除,不再遍历
    {
        add(rec[i].first,rec[i].second),add(rec[i].second,rec[i].first);
        sn[sb[i]]=sn[i],sb[sn[i]]=sb[i];
        if(i==se) se++;
    }
    int num=0,sx,sy;
    for(int i=1;i<=n;i++)
        if((!vis[i]) && (!buk[i])) bfs(i),num++;
    for(int i=k;i>=1;i--)
    {
        ans[i]=num;
        buk[att[i]]=0;
        if(!vis[att[i]]) vis[att[i]]=1,num++;
        for(int j=1;j<=m;j++)
        {

            if((!buk[rec[j].first]) && (!buk[rec[j].second]))
            {
                sx=getfather(rec[j].first),sy=getfather(rec[j].second);
                if(sx!=sy)
                {
                    fa[sx]=sy,num--;
                }
                if(se==j) se++;
                sn[sb[j]]=sn[j],sb[sn[j]]=sb[j];
            }
        }
        if(i==1) cout<<num<<endl;
    }
    for(int i=1;i<=k;i++)
        printf("%d\n",ans[i]);
}

|