码迷,mamicode.com
首页 > 其他好文 > 详细

csu 1601 1601: War (并查集 kruskal)

时间:2015-05-07 23:39:29      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

题意:有n个村子 由m条路联通 其中q条路会依次被摧毁

         问每次摧毁后会有多少片村庄被孤立

思路:首先算出q条路都被摧毁后被孤立的村庄数

        然后再逆序把每条路修复上 每修复一条孤立的村庄就减少一片

        最后再输出每次记录的结果

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int vis[100000+100];
int  fa[100000+100];
int del[100000+100];
int ans[100000+100];
int n,m,q;
struct Edge
{
    int f,to;
};
Edge edge[100000+100];
int fin(int a)
{
    return fa[a]==a?a:fa[a]=fin(fa[a]);
}
int kru(int x,int y)
{
    int fx=fin(x);
    int fy=fin(y);
    if(fx!=fy)
    {
       fa[fx]=fy;
       return 1;
    }
    return 0;
}
int main()
{

    int i,j,k;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=0;i<=n;i++) fa[i]=i;
        memset(vis,0,sizeof(vis));

        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&edge[i].f,&edge[i].to);
        }
        scanf("%d",&q);
        for(i=0;i<q;i++)
        {
            scanf("%d",&del[i]);
            vis[del[i]]=1;
        }
        int cnt=0;
        int tmp=n;
        for(i=1;i<=m;i++)
        {
            if(vis[i]==0)
            {
                if(kru(edge[i].f,edge[i].to)==1) tmp--;
            }
        }
        ans[cnt++]=tmp;
        for(i=q-1;i>0;i--)
        {
            j=del[i];
            if(kru(edge[j].f,edge[j].to)==1) tmp--;
            ans[cnt++]=tmp;
        }
        for(i=cnt-1;i>=0;i--)
        {
            printf("%d",ans[i]);
            if(i!=0) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

  

csu 1601 1601: War (并查集 kruskal)

标签:

原文地址:http://www.cnblogs.com/sola1994/p/4486133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!