数据结构实验之图论六:村村通公路
Time Limit: 1000MS Memory limit: 65536K
题目描述
当前农村公路建设正如火如荼的展开,某乡镇政府决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出的数据表,求使得每个村都有公路连通所需要的最低成本。
输入
连续多组数据输入,每组数据包括村落数目N(N <= 1000)和可供选择的道路数目M(M <= 3000),随后M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个村庄的编号和修建该道路的预算成本,村庄从1~N编号。
输出
输出使每个村庄都有公路连通所需要的最低成本,如果输入数据不能使所有村庄畅通,则输出-1,表示有些村庄之间没有路连通。
示例输入
5 8 1 2 12 1 3 9 1 4 11 1 5 3 2 3 6 2 4 9 3 4 4 4 5 6
示例输出
19
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 100
using namespace std;
typedef struct arcnode
{
int adj;
} arcnode, adjmatrix[110][110];
typedef struct
{
adjmatrix a;
int vn;
int an;
} MG;
void create(MG &g, int n, int m)
{
int i, j;
int v1, v2, w;
g.vn = n;
g.an = m;
for(i=1; i<=g.vn; i++)
for(j=1; j<=g.vn; j++)
{
if(i!=j)
g.a[i][j].adj = INF;
else
g.a[i][j].adj = 0;
}
for(i=1; i<=g.an; i++)
{
scanf("%d %d %d", &v1, &v2, &w);
if(g.a[v1][v2].adj > w||g.a[v2][v1].adj > w)
g.a[v1][v2].adj = w; //有重复边选权值最小的保存
g.a[v2][v1] = g.a[v1][v2];
}
}
struct node
{
int adjvex;//存储已遍历的结点
int lowcost;//存储最小权值
} closedge[110];
int prim(MG &g, int k)
{
int i, j, mincost, sum=0;
for(j=1; j<=g.vn; j++)
if(j!=k)
{
closedge[j].adjvex = k;
closedge[j].lowcost = g.a[k][j].adj;
}
closedge[k].lowcost = 0;//相当于将k点加入U集合(已连接的点集合)
for(i=2; i<=g.vn; i++)
{
//k = minmum(closedge); //求出下一个顶点K
mincost = INF;
for(j=1; j<=g.vn; j++)
if(closedge[j].lowcost<mincost&&closedge[j].lowcost!=0)
{
mincost = closedge[j].lowcost;
k = j;
} //找k的过程
if(mincost == INF)
return -1;
sum += mincost;
closedge[k].lowcost = 0;//相当于将k点加入U集合(已连接的点集合)
for(j=1; j<=g.vn; j++)
if(g.a[k][j].adj<closedge[j].lowcost)//更新原有代价
{
closedge[j].adjvex = k;
closedge[j].lowcost = g.a[k][j].adj;
}
}
return sum;
}
int main()
{
int n, m;
while(~scanf("%d %d", &n, &m))
{
MG g;
create(g, n, m);
printf("%d\n", prim(g, 1));
}
}
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <string.h>
#define INF 0x3f3f3f3f
using namespace std;
int n, m;
int a[110][110];
bool v[110];
int dis[110];
int prim(int k)
{
int i, j, sum=0;
for(i=1; i<=n; i++)
dis[i] = a[k][i];
v[k] = true;
for(i=2; i<=n; i++)
{
int min = INF;
for(j=1; j<=n; j++)
{
if(v[j]==false&&min>dis[j])
{
k = j;
min = dis[j];
}
}
if(min==INF)
return -1;
sum += min;
v[k] = true;
for(j=1; j<=n; j++)
{
if(v[j]==false&&dis[j]>a[k][j])
dis[j] = a[k][j];
}
}
return sum;
}
int main()
{
int v1, v2, i, j, w;
while(~scanf("%d %d", &n, &m))
{
memset(v, 0, sizeof(v));
memset(dis, 0, sizeof(dis));
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
if(i==j)
a[i][j] = 0;
else
a[i][j] = INF;
}
while(m--)
{
scanf("%d %d %d", &v1, &v2, &w);
if(a[v1][v2]>w)
a[v1][v2] = a[v2][v1] = w;
}
printf("%d\n", prim(1));
}
}