某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建快速路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全地区畅通需要的最低成本。
输入格式:
输入的第一行给出村庄数目N (1≤N≤100);随后的N(N−1)/2行对应村庄间道路的成本及修建状态:每行给出4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态 — 1表示已建,0表示未建。
输出格式:
输出全省畅通需要的最低成本。
输入样例:
4
1 2 1 1
1 3 4 0
1 4 1 1
2 3 3 0
2 4 2 1
3 4 5 0
输出样例:
3
源码:
#include <stdio.h>
#include <stdlib.h>
//可以用Krusal也可以用prim,这里当作Kruskal的复习,解题思路有两种:
//1.先把已经修好的路加入到并查集,再用Kruskal算法把森林拼成树
//2.直接把已经修好的路的权重设置为0,然后再去用Prim/Kruskal生成最小生成树(推荐)
#define INFINITY 99999999
#define MaxVertexNum 1010 /* maximum number of vertices */
typedef int Vertex; /* vertices are numbered from 0 to MaxVertexNum-1 */
typedef int WeightType;
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;
int Ne;
WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;
struct Evode{
int Head;
int Tail;
int lowcost;
int if_built;
}Edge[MaxVertexNum*(MaxVertexNum-1)/2+1];
MGraph ReadG(int N)
{
MGraph G=(MGraph)malloc(sizeof(struct GNode));
G->Nv=N;
G->Ne=N*(N-1)/2;
int i,j;
for(i=1;i<=G->Nv;i++)
{
for(j=1;j<=G->Nv;j++)
{
G->G[i][j]=INFINITY;
if(i==j)
{
G->G[i][j]=0;
}
}
}
for(i=1;i<=G->Ne;i++)
{
int a,b,x,y;
scanf("%d%d%d%d",&a,&b,&x,&y);
Edge[i].Head=a;
Edge[i].Tail=b;
Edge[i].lowcost=x;
Edge[i].if_built=y;
G->G[a][b]=x;
G->G[b][a]=x;
if(y==1)
{
Edge[i].lowcost=0;
}
}
return G;
}
void Sort(MGraph G){
int m =G->Ne;
int i;
for(i=1;i<=G->Ne;i++)
{
int min=i;
for(int j=i+1;j<=G->Ne;j++)
{
if(Edge[j].lowcost<Edge[min].lowcost)
min=j;
}
struct Evode t=Edge[i];
Edge[i]=Edge[min];
Edge[min]=t;
}
}
int find(int x,int *set)
{
if(set[x]<0)
return x;
else
return set[x]=find(set[x],set);
}
int lunion(int x,int y,int *set)
{
int px=find(x,set);
int py=find(y,set);
if(px!=py)
{
if(set[px]<=set[py])
{
set[px]+=set[py];
set[py]=px;
}
else
{
set[py]+=set[px];
set[px]=py;
}
return 1;
}
return 0;
}
int count_set(MGraph G,int* set)
{
int i;
int count=0;
for(i=1;i<=G->Nv;i++)
{
if(set[i]<0)
count++;
}
return count;
}
int MiniSpanTree_Kruskal(MGraph G,int *set)
{
int m=1;
int cost=0;
while(m<=G->Ne&&count_set(G,set)!=1)
{
struct Evode t=Edge[m++];
int a,b;
a=t.Head;b=t.Tail;
if(!t.if_built)
{
int f=lunion(a,b,set);
if(f)cost+=t.lowcost;
}
else
{
int f=lunion(a,b,set);
if(f)cost+=t.lowcost;
}
}
return cost;
}
int main()
{
int N;
scanf("%d",&N);
MGraph G=ReadG(N);
Sort(G);
/* for(int i=1;i<=G->Ne;i++)
{
printf("%d\n",Edge[i].lowcost);
}*/
int set[MaxVertexNum];
int i;
for(i=1;i<=G->Nv;i++)
{
set[i]=-1;
}
int cost=MiniSpanTree_Kruskal(G,set);
printf("%d\n",cost);
return 0;
}