1思路:最小生成树+Prime
2注意:n是边数,m是点数。当m为0的时候输出的数“?”。
代码:
#include<algorithm> #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define MAXN 110 #define INF 0xFFFFFFF int n , m; long long ans; long long G[MAXN][MAXN]; int vis[MAXN]; long long lowcost[MAXN]; /*判断是否满足*/ bool judge(){ for(int i = 1 ; i <= m ; i++){ if(!vis[i]) return false; } return true; } /*初始化点之间的距离为无穷大*/ void init(){ for(int i = 1 ; i <= m; i++){ for(int j =1 ; j <= m ; j++) G[i][j] = INF; } } void Prime(){ int i , j , pos , flag; long long min; memset(vis , 0 , sizeof(vis)); vis[1] = 1; ans = 0; for(i = 1 ; i <= m ; i++) lowcost[i] = G[1][i]; for(i = 1 ; i <= m ; i++){ min = INF; for(j = 1 ; j <= m ; j++){ if(!vis[j] && lowcost[j] < min){ min = lowcost[j]; pos = j; } } if(min == INF) break; ans += min; vis[pos] = 1; for(j = 1 ; j <= m ; j++){ if(!vis[j] && lowcost[j] > G[pos][j]) lowcost[j] = G[pos][j]; } } if(judge()) printf("%lld\n" , ans); else printf("?\n"); } int main(){ // freopen("input.txt" , "r" , stdin); int a, b , c; while(scanf("%d%d" , &n , &m) && n){ init(); for(int i = 1 ; i <= n ; i++){ scanf("%d%d%d" , &a , &b , &c); G[a][b] = G[b][a] = c; } if(m) Prime(); else printf("?\n"); } return 0; }