码迷,mamicode.com
首页 > 其他好文 > 详细

【MST+虚拟节点+Kruskal】swjtuOJ 2093

时间:2015-08-07 11:06:02      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:kruskal   mst   虚拟节点   

【MST+虚拟节点+Kruskal】swjtuOJ 2093

【注:交大的看到这篇文章要学会自己写,不要为了比赛而比赛!~】

题目大意

给你n个节点和n个节点的权值,m条连接边,求连通权值的最小和(MST)
n <= 10^5

技术分享
技术分享
技术分享

最小生成树问题,注意原图不一定连通,构造虚拟节点0,0到其他节点边权值赋值为节点权值,求增加2n条边之后的MST即可,注意多加n个节点,数组要开成原来的两倍,笔者RE了一次QAQ~


技术分享

说一下思路

  • 构造虚拟节点很好解决了点权值的问题,保证了图的连通性
  • 节点n比较大,图用邻接表存储,MST采用Kruskal算法,时间慢了一点

?邻接表要开成2倍存放虚拟节点对应的边


参考代码

/* Kruslal + 虚拟节点(点权值) */
/*Author:Hacker_vision*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <climits>
#define eps 1e-8
#define ll long long
#define clr(k,v) memset(k,v,sizeof(k))
using namespace std;

const int _max = 2e5 + 10;
int n,m,u,v,w,cost[_max];

struct Edge{
  int u,v,w;
}edge[_max];//存储边的信息,包括起点\终点\权值
int F[_max];//并查集使用
int tol;//边数,加边前赋值为0
void addedge(int u,int v,int w){
  edge[tol].u = u;
  edge[tol].v = v;
  edge[tol++].w = w;
}
//排序函数,将边按照权值从小到大排序
bool cmp(Edge a,Edge b){
  return a.w < b.w;
}
int find(int x){
 if(F[x]==-1) return x;
 else return F[x] = find(F[x]);
}
//传入点数,返回最小生成树的权值
ll Kruskal(int n){
  clr(F,-1);
  sort(edge,edge+tol,cmp);
  int cnt = 0;//计算加入的边数
  ll ans = 0;
  for(int i = 0; i < tol; ++ i){
    int u = edge[i].u;
    int v = edge[i].v;
    int w = edge[i].w;
    int t1 = find(u);
    int t2 = find(v);
    if(t1 != t2){
        ans += w;
        F[t1] = t2;
        cnt ++;
    }
    if(cnt == n - 1) break;
  }
  if(cnt < n - 1) return -1;
  else return ans;
}
int main(){
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);
  #endif // ONLINE_JUDGE
  while(scanf("%d%d",&n,&m)==2){
    for(int i = 1; i <= n; ++ i) scanf("%d",cost+i);
    tol = 0;
    for(int i = 0; i < m; ++ i){
        scanf("%d%d%d",&u,&v,&w);
        addedge(u,v,w);
    }
    for(int i = 1; i <= n; ++ i)//构造虚拟节点,处理不连通的问题
        addedge(0,i,cost[i]);
    printf("%lld\n",Kruskal(n+1));
  }
  return 0;
}
  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y

版权声明:本文为博主原创文章,未经博主允许不得转载。

【MST+虚拟节点+Kruskal】swjtuOJ 2093

标签:kruskal   mst   虚拟节点   

原文地址:http://blog.csdn.net/u012717411/article/details/47335801

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!