并查集算法。
1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int cnt; //统计最少要添加的道路 7 int set[1001]; 8 9 int find(int a) //查找a的根结点 10 { 11 int x=a; 12 while(set[x] != x) 13 x=set[x]; 14 return x; 15 } 16 17 void merge(int a, int b) //合并a和b的根结点 18 { 19 int x=find(a); 20 int y=find(b); 21 if (x!=y) 22 { 23 set[x]=y; 24 cnt--; //每合并一次最段路径减一 25 } 26 } 27 28 int main() 29 { 30 int a, b; 31 int n, m, i; 32 while(scanf("%d", &n) && n) 33 { 34 cnt=n-1; //初始化最短路径 35 scanf("%d", &m); 36 for (i=1; i<=n; i++) //自己是自己的根结点 37 set[i]=i; 38 for (i=0; i<m; i++) 39 { 40 scanf("%d%d", &a, &b); 41 merge(a, b); 42 } 43 printf("%d\n", cnt); 44 } 45 return 0; 46 }