Make It Connected CodeForces - 1095F (建图+最小生成树)
Make It Connected
You are given an undirected graph consisting of nn vertices. A number is written on each vertex; the number on vertex ii is aiai. Initially there are no edges in the graph.
You may add some edges to this graph, but you have to pay for them. The cost of adding an edge between vertices xx and yy is ax+ayax+ay coins. There are also mm special offers, each of them is denoted by three numbers xx, yy and ww, and means that you can add an edge connecting vertices xx and yy and pay ww coins for it. You don't have to use special offers: if there is a pair of vertices xx and yy that has a special offer associated with it, you still may connect these two vertices paying ax+ayax+ay coins for it.
What is the minimum number of coins you have to spend to make the graph connected? Recall that a graph is connected if it's possible to get from any vertex to any other vertex using only the edges belonging to this graph.
Input
The first line contains two integers nn and mm (1≤n≤2⋅1051≤n≤2⋅105, 0≤m≤2⋅1050≤m≤2⋅105) — the number of vertices in the graph and the number of special offers, respectively.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤10121≤ai≤1012) — the numbers written on the vertices.
Then mm lines follow, each containing three integers xx, yy and ww (1≤x,y≤n1≤x,y≤n, 1≤w≤10121≤w≤1012, x≠yx≠y) denoting a special offer: you may add an edge connecting vertex xx and vertex yy, and this edge will cost ww coins.
Output
Print one integer — the minimum number of coins you have to pay to make the graph connected.
Examples
Input
3 2
1 3 3
2 3 5
2 1 1
Output
5
Input
4 0
1 3 3 7
Output
16
Input
5 4
1 2 3 4 5
1 2 8
1 3 10
1 4 7
1 5 15
Output
18
Note
In the first example it is possible to connect 11 to 22 using special offer 22, and then 11 to 33 without using any offers.
In next two examples the optimal answer may be achieved without using special offers.
题意:
赵老师因为感冒回家进行休息
在睡梦中他竟然来到了一个神奇的地方
这个地方可以抽象为n个点,每个点有一个点权,第i个点的点权为a_i
此时,他的脑海里竟然浮现出了一段文字:
卑鄙的异乡人啊,
你太年轻太简单了,有时还很朴素
我需要给你一些微小的考验
所有点联通之时,
返程之路将浮现。
赵老师知道,想要在点i和点j之间连一条边,所需时间为a_i+a_j
但是作为一个单身多年的魔法师,他可以施展m次魔法,第i次魔法可以在x_i和y_i之间连一条边,所需时间是w_i
赵老师清楚的记得,第二天他还需要上课,因此你需要帮他算出将所有点联通所需的最短时间是多少
思路:
将每一个节点和除了它自己以外的其他n-1个节点中,权值最小的节点相连接。
这样一共是n个边,
还有题目给出的m个边。
在这n+m个边中跑Kruskal算法,求出最小生成树的代价即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline void getInt(int* p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct Edge
{
int f, t;
ll w;
Edge() {}
Edge(int ff, int tt, ll ww)
{
if(ff==9&&tt==4)
{
ff=9;
}
f = ff;
t = tt;
w = ww;
}
};
std::vector<Edge> edge;
bool cmp(Edge a, Edge b)
{
return a.w < b.w;
}
// 并查集部分
int fa[maxn];
int findpar(int x)
{
if (fa[x] == x)
return x;
else
return fa[x] = findpar(fa[x]);
}
void initufs(int n)
{
repd(i, 1, n)
{
fa[i] = i;
}
}
void Merge(int x,int y)
{
x=findpar(x);
y=findpar(y);
if(x!=y)
{
fa[x]=y;
}
}
int n, m; //
ll a[maxn];
ll Kruskal()
{
ll res = 0ll;
initufs(n);
int cnt = 0; // 记录了MST加入了几个节点
for (int i = 0; i < edge.size(); i++)
{
int u = findpar(edge[i].f);
int v = findpar(edge[i].t);
if (u == v)
continue;
Merge(u,v);
res += edge[i].w;
cnt++;
if (cnt == n - 1) // 已经加满了树
break;
}
if (cnt != n - 1)
return -1;
else
return res;
}
typedef pair<ll, int> pli;
pli pre[maxn];
pli last[maxn];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
du2(n, m);
repd(i, 1, n)
{
scanf("%lld", &a[i]);
}
pre[1] = mp(a[1], 1);
last[n] = mp(a[n], n);
repd(i, 2, n)
{
if (a[i] < pre[i - 1].fi)
{
pre[i] = mp(a[i], i);
} else
{
pre[i] = pre[i - 1];
}
}
for (int i = n - 1; i >= 1; --i)
{
if (a[i] < last[i + 1].fi)
{
last[i] = mp(a[i], i);
} else
{
last[i] = last[i + 1];
}
}
edge.push_back(Edge(1, last[2].se, last[2].fi + a[1]));
edge.push_back(Edge(n, pre[n - 1].se, pre[n - 1].fi + a[n]));
repd(i, 2, n - 1)
{
if (last[i + 1].fi < pre[i - 1].fi)
{
edge.push_back(Edge(i, last[i + 1].se, last[i + 1].fi + a[i]));
} else
{
edge.push_back(Edge(i, pre[i - 1].se, pre[i - 1].fi + a[i]));
}
}
repd(i, 1, m)
{
int x, y;
ll z;
scanf("%d %d %lld", &x, &y, &z);
edge.push_back(Edge(x, y, z));
}
sort(ALL(edge), cmp);
if (n == 1)
{
puts("0");
return 0;
}
printf("%lld\n", Kruskal());
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
Make It Connected CodeForces - 1095F (建图+最小生成树)的更多相关文章
- poj 3026 Borg Maze bfs建图+最小生成树
题目说从S开始,在S或者A的地方可以分裂前进. 想一想后发现就是求一颗最小生成树. 首先bfs预处理得到每两点之间的距离,我的程序用map做了一个映射,将每个点的坐标映射到1-n上,这样建图比较方便. ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
- 题解——洛谷P1550 [USACO08OCT]打井Watering Hole(最小生成树,建图)
题面 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pas ...
- Codeforces Round #523 (Div. 2) E. Politics(最小费+思维建图)
https://codeforces.com/contest/1061/problem/E 题意 有n个点(<=500),标记第i个点的代价a[i],然后分别在这n个点建两棵树,对于每颗树的每个 ...
- 区间->点,点->区间,线段树优化建图+dijstra Codeforces Round #406 (Div. 2) D
http://codeforces.com/contest/787/problem/D 题目大意:有n个点,三种有向边,这三种有向边一共加在一起有m个,然后起点是s,问,从s到所有点的最短路是多少? ...
- CodeForces 786B Legacy(线段树优化建图+最短路)
[题目链接] http://codeforces.com/problemset/problem/786/B [题目大意] 给出一些星球,现在有一些传送枪,可以从一个星球到另一个星球, 从一个星球到另一 ...
- Codeforces Round #545 (Div. 2) E 强连通块 + dag上求最大路径 + 将状态看成点建图
https://codeforces.com/contest/1138/problem/E 题意 有n个城市(1e5),有m条单向边(1e5),每一周有d天(50),对于每个城市假如在某一天为1表示这 ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
随机推荐
- centos(linux)--vsftpd配置
1.安装 执行 yum -y install vsftpd 注:(1)是否使用sudo权限根据个人的具体情况 (2)rpm -qa | grep vsftpd 可以通过这个检查是否已经安装vsftpd ...
- KVM虚拟化介绍(1)
一.虚拟化分类 1.虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独 立的空间内运 ...
- c++学习笔记_5
前言:本笔记所对应的课程为中国大学mooc中北京大学的程序设计与算法(三)C++面向对象程序设计,主要供自己复习使用,且本笔记建立在会使用c和java的基础上,只针对与c和java的不同来写 继承 继 ...
- OpenCV3编程入门.知识点
1. 第三部分 掌握 imgproc 组件 第六章 图像处理 6.1.线性滤波: Pdf.P170 Pdf.P171 平滑处理(smoothing)(模糊处理(bluring))-- 使用频率很高 - ...
- 最新 盛趣游戏java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.盛趣游戏等10家互联网公司的校招Offer,因为某些自身原因最终选择了盛趣游戏.6.7月主要是做系统复习.项目复盘.Leet ...
- lua程序设计 第一章习题答案
练习1.1:运行阶乘的示例并观察,如果输入负数,程序会出现什么问题?试着修改代码来解决问题. 答:当输入负数时,循环无法终止,因为原本程序中的终止条件为n==0,而在输入为负数情况下,无法达成此终止条 ...
- rqnoj PID95:多多看DVD(加强版)
题目描述 多多进幼儿园了,今天报名了.只有今晚可以好好放松一下了(以后上了学后会很忙).她的叔叔决定给他买一些动画片DVD晚上看.可是爷爷规定他们只能在一定的时间段L看完.(因为叔叔还要搞NOIP不能 ...
- StormUI各参数详解
参考:http://www.malinga.me/reading-and-understanding-the-storm-ui-storm-ui-explained/
- poj1410(判断线段和矩形是否相交)
题目链接:https://vjudge.net/problem/POJ-1410 题意:判断线段和矩形是否相交. 思路:注意这里的相交包括线段在矩形内,因此先判断线段与矩形的边是否相交,再判断线段的两 ...
- HTML 全局属性 = HTML5 中添加的属性。
属性 描述 accesskey 规定激活元素的快捷键. class 规定元素的一个或多个类名(引用样式表中的类). contenteditable 规定元素内容是否可编辑. contextmenu 规 ...