POJ 2421 Constructing Roads 最小生成树

编程技术  /  houtizong 发布于 3年前   123

来源:http://poj.org/problem?id=2421

题意:还是给你n个点,然后求最小生成树。特殊之处在于有一些点之间已经连上了边。

思路:对于已经有边的点,特殊标记一下,加边的时候把这些边的权值赋值为0即可。这样就可以既保证这些边一定存在,又保证了所求的结果正确。

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <string.h>#include <climits>using namespace std;#define CLR(arr,val) memset(arr,val,sizeof(arr))const int N = 110;int father[N];struct edge{int lp,rp,value;}ee[N*N];int map[N][N],flag[N][N],numedge,n;bool cmp(edge a,edge b){return a.value < b.value;}int find(int x){if(x == father[x])return father[x];return find(father[x]);}bool Union_Set(int x,int y){int fx = find(x);int fy = find(y);if(fx == fy){  return false;}else{  father[fx] = fy;  return true;}}int kruskal(){sort(ee,ee+numedge,cmp);for(int i = 1; i <= n; ++i)father[i] = i;int sum = 0;for(int i = 0; i < numedge; ++i){int lx = ee[i].lp;int rx = ee[i].rp;if(Union_Set(lx,rx)){sum += ee[i].value;}}return sum;}int main(){//freopen("1.txt","r",stdin);while(scanf("%d",&n) != EOF){      CLR(flag,0);for(int i = 1; i <= n; ++i){  for(int j = 1; j <= n; ++j)  scanf("%d",&map[i][j]);}        int m,x,y;scanf("%d",&m);while(m--){  scanf("%d%d",&x,&y);  flag[x][y] = 1;}numedge = 0;for(int i = 1; i < n; ++i){for(int j = i + 1; j <= n; ++j){if(flag[i][j]){ee[numedge].lp = i;ee[numedge].rp = j;ee[numedge].value = 0;numedge++;}else{ee[numedge].lp = i;ee[numedge].rp = j;ee[numedge].value = map[i][j];numedge++;}}}int ans = kruskal();printf("%d\n",ans);}return 0;}


更多详细信息请查看java教程网 http://www.itchm.com/forum-59-1.html

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客