并查集 Junk-Mail Filter hdu 2473

来源:互联网 发布:相机镜头数据 编辑:程序博客网 时间:2024/05/19 02:19

输入N M,表示N个点,M组数据

接下来M组数据

M表示连接A B

S表示删除点A

计算共有多少组边

提示

1)删除点不是将与它相连的边剪断,而只是消除这个点

2)开两个数组,f[maxn]和p[maxn],表示i对应的真正值和i的父节点

#include <stdio.h>#include <string.h>#define maxn 1000001int f[maxn];               //表示i对应的真实值int p[maxn];               //表示i的父节点int flag[maxn];            //计算多少组int find(int i)           //查找根节点{if(i==p[i])return p[i];p[i]=find(p[i]);return p[i];}int main(){int n,k;int i,j;char s[3];int a,b;int fr,ed;int sum;int time=0;while(scanf("%d%d",&n,&k)!=-1){time++;if(n==0&&k==0)break;for(i=0;i<n;i++)             //初始化{f[i]=i;p[i]=i;}sum=n;for(i=0;i<k;i++){scanf("%s",s);if(s[0]=='M'){scanf("%d%d",&a,&b);fr=find(f[a]);ed=find(f[b]);if(fr!=ed)p[fr]=ed;}else{scanf("%d",&a);f[a]=sum;           //将f[a]的值赋为sum,则原来的f[a]在也无法访问,相当于删除点,而边并未剪断p[sum]=sum;          //给新的节点父节点sum++;}}sum=0;memset(flag,0,sizeof(flag));for(j=0;j<n;j++){fr=find(f[j]);if(flag[fr]==0){flag[fr]=1;sum++;}}printf("Case #%d: %d\n",time,sum);}return 0;}


0 0
原创粉丝点击