最小生成树的一个小变形。主要处理的问题在于究竟如何判断,也就是在数据中如何处理某条路径已经修建好了的问题。
只要一个小技巧就可以达到目的:将已经修建好了的路径的权值赋值为0,这样,修建这条路的时候不用花费MONEY,得到的最小值不还是要求的最小值吗?注意将问题转换成简单的处理过程,这需要时间的训练吧
#include <iostream>
using namespace std;
int map[102][102], n, vis[102], lowercost[102], m, buildNum;
#define MAX 0x7fffffff
int Prim(int v)
{
int i,j, min=0, tmp_min;
vis[v] = 1;
for(i=1; i<=n; i++)
lowercost[i] = map[v][i];
for(i=2; i<=n; i++)
{
tmp_min=MAX;
for(j=1; j<=n; j++)
if(tmp_min>lowercost[j] && vis[j]==0)
{
tmp_min = lowercost[j];
v = j;
}
vis[v] = 1;
min+=tmp_min;
for(j=1; j<=n; j++)
if(lowercost[j]>map[v][j] && vis[j]==0)
lowercost[j] = map[v][j];
}
return min;
}
void init()
{
int i, j, a, b, c, d;
memset(vis, 0, sizeof(vis));
memset(lowercost,0,sizeof(lowercost));
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
map[i][j] = MAX;
m = n*(n-1)/2;
for(i=1; i<=m; i++)
{
cin>>a>>b>>c>>d;
if(d==0)//如果d==1表示路径已经建立好了,就不需要在建立,即:保持a,b之间的权值为0。
{
map[a][b] = map[b][a] = c;
}
else
map[a][b] = map[b][a] = 0;
}
}
void main()
{
while(cin>>n && n)
{
buildNum=0;//已经建立好的路得数目
init();
cout<<Prim(1)<<endl;
}
}