题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102
3 0 990 692 990 0 179 692 179 0 1 1 2
179
代码例如以下:
#include <cstdio> #include <cstring> #define INF 0x3f3f3f3f #define MAXN 517 //创建m二维数组储存图表,low数组记录每2个点间最小权值,visited数组标记某点是否已訪问 int m[MAXN][MAXN], low[MAXN], visited[MAXN]; int n; int prim( ) { int i, j; int pos, minn, result=0; // memset(visited,0,sizeof(visited)); for(i = 1; i <= n; i++) visited[i] = 0; visited[1] = 1; pos = 1; //从某点開始,分别标记和记录该点 for(i = 1; i <= n; i++) //第一次给low数组赋值 { if(i != pos) low[i] = m[pos][i]; else low[i] = 0; } for(i = 1; i <= n; i++) //再执行n-1次 { minn = INF; //找出最小权值并记录位置 pos = -1; for(j = 1; j <= n; j++) { if(visited[j]==0 && minn>low[j]) { minn = low[j]; pos = j; } } if(pos == -1) continue; result += minn; //最小权值累加 visited[pos] = 1; //标记该点 for(j = 1; j <= n; j++) //更新权值 if(!visited[j] && low[j]>m[pos][j]) low[j] = m[pos][j]; } return result; } int main() { int tt; while(~scanf("%d",&n)) { memset(m,INF,sizeof(m)); //全部权值初始化为最大 for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { scanf("%d",&tt); if(tt < m[j][i]) m[i][j] = m[j][i] = tt; } } int Q, a, b; scanf("%d",&Q); for(int i = 0; i < Q; i++) { scanf("%d%d",&a,&b); m[a][b] = m[b][a] = 0; } int ans = prim( ); printf("%d\n",ans); } return 0; }