hdu1232 并查集
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1213/
题目给定n个点和一些边,只要两点能通过某些边相连就相通。我们只要把所有的点连成一棵树就可以,一棵树有n-1条边,每次合并两棵树的时候边都会增加一条,我们只要知道合并的次数就可以知道已经有了多少条边,并查集的合并次数是n-1,因为最多n-1条边就使得每两个结点联通。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define mp(a,b) make_pair((a),(b)) 17 #define P pair<int,int> 18 #define dbg(args) cout<<#args<<":"<<args<<endl; 19 #define inf 0x3f3f3f3f 20 const int maxn=1e6+10; 21 int n,m,t; 22 inline int read(){ 23 int ans=0,w=1; 24 char ch=getchar(); 25 while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();} 26 while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 27 return ans*w; 28 } 29 int f[maxn],cnt; 30 void init() 31 { 32 f(i,1,n)f[i]=i; 33 cnt=0; 34 } 35 int find(int x) 36 { 37 if(x==f[x])return x; 38 return f[x]=find(f[x]); 39 } 40 void Union(int x,int y) 41 { 42 int fx=find(x); 43 int fy=find(y); 44 if(fx==fy)return ; 45 else { 46 f[fx]=fy; 47 cnt++; 48 } 49 } 50 int main() 51 { 52 //freopen("input.txt","r",stdin); 53 //freopen("output.txt","w",stdout); 54 std::ios::sync_with_stdio(false); 55 int a,b; 56 while(n=read()) 57 { 58 init(); 59 m=read(); 60 f(i,1,m)a=read(),b=read(),Union(a,b); 61 pf("%d\n",n-1-cnt); 62 63 } 64 }
每一个不曾起舞的日子,都是对生命的辜负。