40分 WA求调 已过样例

P1197 [JSOI2008] 星球大战

Xeqwq @ 2022-08-08 20:55:09

#include <iostream>
#include <vector>
using namespace std;
int n,m,k;
const int Maxn=400005;
int fa[Maxn];
int find(int x)
{
    if(fa[x]==x) return x;
    fa[x]=find(fa[x]);
    return fa[x];
}
void merge(int x,int y)
{
    fa[find(x)]=find(y);
}
vector<int> adj[Maxn];
int ord[Maxn];
int ruin[Maxn],ans[Maxn];
int f[Maxn];
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) fa[i]=i;
    int u,v;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    cin>>k;
    for(int i=1;i<=k;i++)
    {
        scanf("%d",&ord[i]);
        ruin[ord[i]]=1;
    }
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        if(ruin[i]) continue;
        for(int j=0;j<adj[i].size();j++)
        {
            if(!ruin[adj[i][j]])
                merge(adj[i][j],i);
        }
    }
    for(int i=0;i<n;i++)
    {
        if(ruin[i]) continue;
        if(!f[i])
        {
            f[i]=1;
            cnt++;
        }
    }
    ans[k+1]=cnt;
    for(int i=k;i>=1;i--)
    {
        cout<<ord[i]<<" ";
        ruin[ord[i]]=0;
        cnt++;
        for(int j=0;j<adj[ord[i]].size();j++)
        {
            cout<<adj[ord[i]][j]<<" ";
            if(!ruin[adj[ord[i]][j]])
            {
                if(find(ord[i])!=find(adj[ord[i]][j]))
                {
                    cnt--;
                    merge(ord[i],adj[ord[i]][j]);
                }
            }
        }
        cout<<endl;
        ans[i]=cnt;
    }
    for(int i=1;i<=k+1;i++)
        printf("%d\n",ans[i]);
}

by 泥土笨笨 @ 2022-08-08 22:01:32

@Xeqwq 没看懂这一段:

for (int i = 0; i < n; i++) {
    if (ruin[i]) continue;
    if (!f[i]) {
        f[i] = 1;
        cnt++;
    }
}

题目中问的是最后结束的时候剩下的连通块的个数,楼主求的是剩下没被摧毁的点的个数?


by Xeqwq @ 2022-08-08 22:07:24

@泥土笨笨 感谢 已过!


|