畅通工程HDU1232(并查集)
http://acm.hdu.edu.cn/showproblem.php?pid=1232
有n个城市,现在已经有了k条路,求最少还要多少条路可以让他们全部链接起来
算法核心:并查集,吧可以连通的连在一起,最后求共有几个大块
先做预处理P[i]=i;然后就是
1 int find(int x) 2 { 3 return x==p[x]?x:find(p[x]); 4 } 5 void merg(int x,int y) 6 { 7 int a=find(x); 8 int b=find(y); 9 if(a!=b) 10 { 11 p[a]=b; 12 } 13 }
经过这个运算后,样例1就变成了
3 2
/ \
1 4
也就是p[1]=3;p[4]=3; p[1]=1;p[2]=2;
就被分成了两个部分,也就是说需要一条路
附代码:
1 #include <stdio.h> 2 #include <string.h> 3 #define max(a,b) (a)>(b)?(a):(b) 4 #define min(a,b) (a)<(b)?(a):(b) 5 6 int p[1005]; 7 int n,k; 8 int find(int x) 9 { 10 return x==p[x]?x:find(p[x]); 11 } 12 void merg(int x,int y) 13 { 14 int a=find(x); 15 int b=find(y); 16 if(a!=b) 17 { 18 p[max(a,b)]=min(a,b); 19 } 20 } 21 int main() 22 { 23 while(~scanf("%d",&n) && n) 24 { 25 int i; 26 for(i=1;i<=n;i++) 27 { 28 p[i]=i; 29 } 30 scanf("%d",&k); 31 int a,b; 32 while(k--) 33 { 34 scanf("%d%d",&a,&b); 35 merg(a,b); 36 } 37 int count=-1; 38 for(i=1;i<=n;i++) 39 { 40 if(p[i]==i)count++; 41 } 42 printf("%d\n",count); 43 } 44 return 0; 45 }