#include <stdio.h>#include <string>#define SIZE 1100#define INF 0x7fffffffint map[1100][1100], weight[1100], pre[1100], length, point; bool sign[1100];void prim(int weight[],int map[][SIZE], int pre[], bool sign[], int &length, int point_num, int source, int &point){ point =1; //source源起点,一定要是路径中有的 for(int i=1; i<=point_num; i++) //这里的路径的标号都 > 1,记录所以点到源起点的权值,前驱,将该点置为已经查找 { weight[i] = map[source][i]; pre[i] = source; sign[i] = true; } sign[source] = false; length = 0; for(int i=1; i<point_num; i++) //枚举n-1个点,即n-1个通路 { int min = INF, sign_node = i; //sign_node 记录找到的最小的下一个点 for(int j=1; j<=point_num; j++) //查找最小权值的路径 { if(sign[j] && weight[j] < min) {min = weight[j]; sign_node = j; } } {sign[sign_node] = false; length += min; } if(min != INF ) point++; //可以在这里添加一个标记,使他值等于min,如果最后值等于最大值,则不能生成最小生成树 for(int j=1; j<=point_num; j++) //重新设定源起点,将剩下的未找的点加入 { if(weight[j] > map[sign_node][j] && sign[j] ) {weight[j] = map[sign_node][j]; pre[j] = sign_node;} } }}int a;void input(int n, int map[][SIZE]){ for(int i=1; i<=n ;i++) { int b; scanf("%d%d", &a, &b); map[a][b] = 0; map[b][a] = 0; }}int main(){ int N,M; while(scanf("%d %d", &N, &M) && N ) { //scanf("%d", &M); for(int i=0; i<=N; i++) //初始化 { weight[i] = INF; pre[i] = 0; for(int j=0; j<=N; j++) map[i][j] = INF; } memset(sign, false, sizeof(sign) ); length = point = 0; input( M, map); prim(weight, map, pre, sign, length, N, a, point); //查找,注意这个1 它是源起点,一定要是在路径上已知的点 printf("%d
", N-point); } return 0;}