现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例:
12
/*哈利·波特的考试*/
/*思路:1.判断是不是连通图,如果不是则输出0;
2.多源最短路径,对联通图中的每一个顶点遍历,得到每一个顶点与其他顶点的最大长度*/
/*邻接矩阵,无向图*/
/*1.忘记加取址符
2.错在对角线没有初始为0
3.无解的输出位置错误
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Gnode* MGraph;
struct Gnode {
int Nv; /*顶点数*/
int Ne; /*边数*/
int G[101][101]; /*权重*/
};
/*边的定义,无权边*/
typedef struct Enode* Edge;
struct Enode {
int V1, V2;
int weight;/*权重*/
};
/*队列操作*/
typedef struct Qnode* ptrtoQnode;
struct Qnode {
int* Data;/*data数组,*/
int front, rear;/*队列头尾指针*/
int maxsize;/*容量*/
};
typedef ptrtoQnode Queue;
int AddQ(Queue Q, int x);
Queue CreateQueue(int maxsize);
int isempty(Queue Q);
int DeleteQ(Queue Q);
/*操作函数*/
MGraph creatgraph(int size);
void insert(MGraph g, Edge e);
MGraph buildgraph(int N);
int isedge(MGraph graph, int a, int b);
void BFS(MGraph graph, int N, int* visited, int s);
void Floyd(MGraph graph,int weight[][101]);
/*队列操作*/
int AddQ(Queue Q, int x);
Queue CreateQueue(int maxsize);
int isempty(Queue Q);
int DeleteQ(Queue Q);
int main() { /*注意此题从1开始*/
int N;
scanf("%d", &N);
int* visited = (int*)malloc((N+1) * sizeof(int));
int isanswer = 1;
for (int i = 1; i < N+1; i++) {
visited[i] = 0;
}
/*建立邻接矩阵*/
MGraph graph = buildgraph(N);
BFS(graph, N, visited, 1);/*以第一个顶点为起点,对图进行遍历,如果图中有顶点未被遍历过则说明不是联通图*/
for (int i = 1; i < N + 1; i++) {
if (visited[i] == 0) {
isanswer = 0;
break;
}
}
/*多源最短路径*/
int weight[101][101];
int shortest[101];
Floyd(graph, weight);
for (int i = 1; i < N + 1; i++) {
int max = -1;
for (int j = 1; j < N + 1; j++) {
if (weight[i][j] > max && weight[i][j] != 20000) {
max = weight[i][j];
}
}
shortest[i] = max;/*将与第i个顶点路径最长的存储*/
}
/*先将shortest存储*/
int data[101];
for (int i = 1; i < N + 1; i++) {
data[i] = shortest[i];
}
/*对shortest排序,找出其最小值*/
int j;
int temp;
for (int i = 1; i < N ; i++) { /*shortest最小值即第一元素*/
for (j = i + 1; j < N + 1; j++) {
if (shortest[i] > shortest[j]) {
temp = shortest[i];
shortest[i] = shortest[j];
shortest[j] = temp;
}
}
}
/*找出最小编号*/
int answer;
for (int i = 1; i < N + 1; i++) {
if (shortest[1] == data[i]) {
answer = i;
break;
}
}
if(isanswer == 1){
printf("%d %d", answer, data[answer]);
}
else printf("0");
return 0;
}
MGraph creatgraph(int size) {/*初始化邻接矩阵*/
int j;
MGraph graph = (MGraph)malloc(sizeof(struct Gnode)); /*建图*/
graph->Nv = size;
graph->Ne = 0;
/*初始化邻接矩阵*/
for (int i = 1; i < graph->Nv+1; i++) {
for (j = 1; j < graph->Nv+1; j++) {
if(i==j){ /*一开始没有将对角线处初始为0,导致最后多源最短路径出错*/
graph->G[i][j] = 0;
}
else{
graph->G[i][j] = 20000; /*设20000为无穷值,即两点不连通*/
}
}
}
return graph;
}
void insert(MGraph g, Edge e) { /*注意此题为无向图*/
g->G[e->V1][e->V2] = e->weight;
g->G[e->V2][e->V1] = e->weight;
}
MGraph buildgraph(int N) {
MGraph G;
G = creatgraph(N);
scanf("%d", &G->Ne);
if (G->Ne != 0) {
Edge E = (Edge)malloc(sizeof(struct Enode));
for (int i = 0; i < G->Ne; i++) {
scanf("%d %d %d", &E->V1, &E->V2,&E->weight);
insert(G, E);
}
}
return G;
}
Queue CreateQueue(int maxsize) {
Queue Q = (Queue)malloc(sizeof(struct Qnode));
Q->Data = (int*)malloc(maxsize * sizeof(int));
Q->front = Q->rear = 0;
Q->maxsize = maxsize;
return Q;
}
int AddQ(Queue Q, int x) {
Q->rear = (Q->rear + 1) % (Q->maxsize);
Q->Data[Q->rear] = x;
return 1;
}
int isempty(Queue Q) {
return(Q->rear == Q->front);
}
int DeleteQ(Queue Q) {
Q->front = (Q->front + 1) % Q->maxsize;
return Q->Data[Q->front];
}
int isedge(MGraph graph, int a, int b) {
return graph->G[a][b] < 20000 ? 1 : 0;
}
void BFS(MGraph graph, int N, int* visited, int s) {
Queue Q;
int v, w;
Q = CreateQueue(N);
visited[s] = 1;
AddQ(Q, s);
while (isempty(Q) == 0) {
v = DeleteQ(Q);
for (w = 1; w < graph->Nv + 1; w++) {/*遍历图中的每一个顶点*/
if (visited[w] == 0 && isedge(graph, v, w)==1) {
visited[w] = 1;
AddQ(Q, w);
}
}
}
}
void Floyd(MGraph graph,int weight[][101]) {
int i, j, k;
for (i = 1; i < graph->Nv + 1; i++) {
for (j = 1; j < graph->Nv + 1; j++) {
weight[i][j] = graph->G[i][j];
}
}
for (k = 1; k < graph->Nv + 1; k++) {
for (i = 1; i < graph->Nv + 1; i++) {
for (j = 1; j < graph->Nv + 1; j++) {
if (weight[i][k] + weight[k][j] < weight[i][j]) {
weight[i][j] = weight[i][k] + weight[k][j];
}
}
}
}
}