Hdu-3371 Connect the Cities

来源:互联网 发布:小甲鱼c语言 百度网盘 编辑:程序博客网 时间:2024/05/07 16:31

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3371

题目大意:给你很多条边,包括顶点和权值。再给你一些点,表示这些点已经有图连通,求最小生成树的权值之和。

解题思路:

将后来的连通的边的权值设定为0就可以了。就是比较裸的最小生成树。。。但是细节处理比较麻烦,我就是处理后来那些连通顶点花了很长时间,而且是卡过去了。。题目要求1s。我968ms。看来需要优化。。。。。。。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define INF 0x3f3f3f3f#define MAXN 510int map[MAXN][MAXN], lowcost[MAXN];bool visit[MAXN];int alr[MAXN];int num, sum;void prim(){int temp, k;memset(visit, false, sizeof(visit));for(int i = 1; i <= num; ++i)lowcost[i] = map[1][i];sum = 0;visit[1] = true;for(int i = 1; i <= num; ++i){temp = INF;for(int j = 1; j <= num; ++j)if(!visit[j] && temp > lowcost[j])temp = lowcost[k = j];if(temp == INF)break;visit[k] = 1;sum += temp;for(int j = 1; j <= num; ++j)if(!visit[j] && lowcost[j] > map[k][j])lowcost[j] = map[k][j];}}int main(){int ncase;int road, already;int a, b, cost;int nodenum, node;bool flag;scanf("%d", &ncase);while(ncase--){flag = true;memset(alr, INF, sizeof(alr));memset(map, INF, sizeof(map));scanf("%d%d%d", &num, &road, &already);for(int i = 1; i <= road; ++i){scanf("%d%d%d", &a, &b, &cost);if(cost < map[a][b])map[a][b] = map[b][a] = cost;}for(int i = 1; i <= already; ++i) //处理这些权值为0的边{scanf("%d", &nodenum);for(int j = 1; j <= nodenum; ++j)scanf("%d", &alr[j]);int k;for(int j = 1; j < nodenum; ++j){k = j + 1;map[alr[j]][alr[k]] = map[alr[k]][alr[j]] = 0;}}prim();for(int i = 1; i <= num; ++i) //判断图的连通性if(visit[i] == false)flag = false;if(flag)printf("%d\n", sum);elseprintf("-1\n");}return 0;}


原创粉丝点击