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;}
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!
技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成
网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];
文章归档
文章标签
友情链接