标签:include http 生成 images cst sci 最小 getch 测试用例
题目:
输入边的两端点和边值,求最小生成树(最小支撑树)的值。
思路:
过程:
本题调试问题出在如下几处:
1.用%c会读入回车符(用getchar()有的平台又会出问题),所以以后读字符都直接用%s,然后在取字符串第一个字符即可。
char c[4];
scanf("%s",c);
printf("%c",c[0]);
2.边排序后遍历所有边,我犯了个错(以为只要所有点都出现过,那后面的边就不用遍历了),忘记了即使所有点都出现过,
也可能分散在多个连通分量内,所以最小支撑树不一定已生成。最保险的方式还是把所有边,一个个全遍历完。
3.本题测试用例不太符合题目要求,既有A 1 A 24这种自环边,也有D 2 A 45 C 5这种(ASCII大的后面跟小的),重复的A 2 B 44 B 100.
代码:
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; //边结构体 struct Edge{ char Node1; //边的两点 char Node2; int value; //边值 }; //相关变量和函数 Edge edge[77]; //边数组 int inputNum; //输入边的个数 int joinMark[26]; //A-Z是否参与,0:没参加;1:参加 char storeTree[26]; //并查集,存树 char find(char c){ //查找结点c的根 char cc=c; while(storeTree[cc-65]!=cc){ cc=storeTree[cc-65]; } return cc; } bool cmp(Edge e1,Edge e2){ //边值大小比较函数 if(e1.value<=e2.value) return true; return false; } //主函数 int main(){ int n,n2,i,sum; //n:参与点的个数,n2:n的备份,sum:支撑树的边和 char node1[5],node2[5]; //边的两点 int k,cost; //k:每行输入k个边;cost:边的值 while(scanf("%d",&n)!=EOF && n){ //输入n(n=0时退出) //memset(edge,0,77*sizeof(Edge)); //初始化变量值 inputNum=0; memset(joinMark,0,26*sizeof(int)); for(i=0;i<26;i++) storeTree[i]=char(i+65); sum=0; n2=n; //边的输入 while(--n2){ //n-1行输入 scanf("%s %d",node1,&k); while(k--){ //每行k个边 scanf("%s %d",node2,&cost); edge[inputNum].Node1=node1[0]; edge[inputNum].Node2=node2[0]; edge[inputNum].value=cost; inputNum++; } } sort(edge,edge+inputNum,cmp); //把边按值从小到大的顺序排列 i=0; while(i<inputNum){ //找最小支撑树 //边的两点都未参加 if(joinMark[edge[i].Node1-65]==0 && joinMark[edge[i].Node2-65]==0){ if(edge[i].Node1==edge[i].Node2){ //自己指向自己的边不算 i++; continue; } if(edge[i].Node1<edge[i].Node2) //ASCII码小的为父结点 storeTree[edge[i].Node2-65]=edge[i].Node1; else storeTree[edge[i].Node1-65]=edge[i].Node2; //边的两点都参加 joinMark[edge[i].Node1-65]=joinMark[edge[i].Node2-65]=1; sum+=edge[i].value; //边值加入sum } else{ //至少一点已参加 //两点都已参加 if(joinMark[edge[i].Node1-65]==1 && joinMark[edge[i].Node2-65]==1){ if(edge[i].Node1==edge[i].Node2){ //自己指向自己的边跳过 i++; continue; } char root1,root2; //两点属于不同连通量 if((root1=find(edge[i].Node1))!=(root2=find(edge[i].Node2))){ if(root1<root2){ //哪个根的ASCII码小,则为父结点 storeTree[root2-65]=root1; sum+=edge[i].value; } else{ storeTree[root1-65]=root2; sum+=edge[i].value; } } } else{ //只一个点已参加 if(joinMark[edge[i].Node1-65]==1){ //已参加的点为父结点 storeTree[edge[i].Node2-65]=edge[i].Node1; joinMark[edge[i].Node2-65]=1; } else{ storeTree[edge[i].Node1-65]=edge[i].Node2; joinMark[edge[i].Node1-65]=1; } sum+=edge[i].value; //边值加入sum } } i++; //跳到下一边 } printf("%d\n",sum); //输出结果 } return 0; }
标签:include http 生成 images cst sci 最小 getch 测试用例
原文地址:http://www.cnblogs.com/songshu-gancuimian/p/6649799.html