【NOIP2015模拟10.22】最小代价
前言
本来在比赛上就想到最小生成树了,但不相信这道题那么简单,然后就没有然后了。。。
题目
给出一幅由n个点m条边构成的无向带权图。
其中有些点是黑点,其他点是白点。
现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个黑点,可以选取其中任意一个),我们想要使得花费的代价最小。请问这个最小代价是多少?
注意:最后选出的边保证每个白点到离它最近的黑点的距离仍然等于原图中的最短距离。
分析
这道题最麻烦的地方就是最终搞成的图有可能有很多个联通块。
增加一个点:0点,让0点连接所有的黑点,边权为0;
处理从S发到每个点的最短距离
题目要求最小的总距离,显然搞一遍最小生成树就可以了。
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483747;
using namespace std;
long long b[710000][4],dis[710000],next[710000],last[710000],a[710000],fa[710000],ans,tot,n,m,v[710000],d[8000000];
bool bz[710000];
void q(long long l,long long r)
{
long long i=l,j=r;
long long mid=b[(l+r)/2][0],e;
while(i<j)
{
while(b[i][0]<mid) i++;
while(b[j][0]>mid) j--;
if(i<=j)
{
e=b[i][0];
b[i][0]=b[j][0];
b[j][0]=e;
e=b[i][1];
b[i][1]=b[j][1];
b[j][1]=e;
e=b[i][2];
b[i][2]=b[j][2];
b[j][2]=e;
i++;
j--;
}
}
if(i<r) q(i,r);
if(l<j) q(l,j);
}
int spfa()
{
long long head=0,tail=1,k;
fill(dis,dis+n+m+1,maxlongint*3);
fill(bz,bz+n+m+1,true);
d[1]=0;
dis[0]=0;
while(head<tail)
{
k=d[++head];
bz[k]=true;
for(long long i=last[k];i;i=next[i])
{
if(dis[a[i]]>dis[k]+v[i])
{
dis[a[i]]=dis[k]+v[i];
if(bz[a[i]])
{
d[++tail]=a[i];
bz[a[i]]=false;
}
}
}
}
}
bool dg(long long x)
{
long long i,j;
for(i=last[x];i;i=next[i])
{
long long y=a[i];
if(dis[x]+v[i]==dis[y])
{
dg(y);
b[++tot][1]=x;
b[tot][2]=y;
b[tot][0]=v[i];
}
}
return true;
}
long long get(long long x)
{
if(x==fa[x]) return x;
long long y=get(fa[x]);
fa[x]=y;
return y;
}
int kruskal()
{
long long i,j,k,l,x,y;
for(i=1;i<=tot;i++)
{
x=get(b[i][1]);
y=get(b[i][2]);
if(x!=y)
{
ans+=b[i][0];
fa[y]=x;
}
}
}
int bj(long long x,long long y,long long k)
{
fa[y]=y;
next[++tot]=last[x];
last[x]=tot;
v[tot]=k;
a[tot]=y;
}
int main()
{
scanf("%lld%lld",&n,&m);
long long i,j,k,l,x,y;
for(i=1;i<=n;i++)
{
scanf("%lld",&x);
if(x) bj(0,i,0);
}
for(i=1;i<=m;i++)
{
scanf("%lld%lld%lld",&x,&y,&k);
bj(x,y,k);
bj(y,x,k);
}
spfa();
tot=0;
dg(0);
q(1,tot);
bool b1=maxlongint;
kruskal();
if(ans==0) cout<<"impossible";else
cout<<ans;
}
【NOIP2015模拟10.22】最小代价的更多相关文章
- [NOIP2015模拟10.22] 最小代价 解题报告 (最小生成树)
Description 给出一幅由n个点m条边构成的无向带权图.其中有些点是黑点,其他点是白点.现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个黑点,可以选取其中任意一个),我们想要使得 ...
- [NOIP2015模拟10.22] 最大子矩阵 解题报告(单调栈)
Description 我们将矩阵A中位于第i行第j列的元素记作A[i,j].一个矩阵A是酷的仅当它满足下面的条件: A[1,1]+A[r,s]<=A[1,s]+A[r,1](r,s ...
- JZOJ 4273. 【NOIP2015模拟10.28B组】圣章-精灵使的魔法语
4273. [NOIP2015模拟10.28B组]圣章-精灵使的魔法语 (File IO): input:elf.in output:elf.out Time Limits: 1000 ms Mem ...
- JZOJ 4269. 【NOIP2015模拟10.27】挑竹签
4269. [NOIP2015模拟10.27]挑竹签 (File IO): input:mikado.in output:mikado.out Time Limits: 1000 ms Memory ...
- JZOJ 4272. 【NOIP2015模拟10.28B组】序章-弗兰德的秘密
272. [NOIP2015模拟10.28B组]序章-弗兰德的秘密 (File IO): input:frand.in output:frand.out Time Limits: 1000 ms M ...
- [jzoj]4271. 【NOIP2015模拟10.27】魔法阵(37种转移的dp)
题意不说 应该这辈子都不会忘记了... 这是我人生中做的最SB的一道DP题. 真的打的我心态崩了.... 可是竟然被我调出来了..... 也是没谁了... 我们设\(F[i][j][S]\)表示到第\ ...
- [JZOJ4272] [NOIP2015模拟10.28B组] 序章-弗兰德的秘密 解题报告(树形DP)
Description 背景介绍弗兰德,我不知道这个地方对我意味着什么.这里是一切开始的地方.3年前,还是个什么都没见过的少年,来到弗兰德的树下,走进了封闭的密室,扭动的封尘已久机关,在石板上知道了这 ...
- [NOIP2015模拟10.27] 挑竹签 解题报告(拓扑排序)
Description 挑竹签——小时候的游戏夏夜,早苗和诹访子在月光下玩起了挑竹签这一经典的游戏.挑竹签,就是在桌上摆上一把竹签,每次从最上层挑走一根竹签.如果动了其他的竹签,就要换对手来挑.在所有 ...
- [NOIP2015模拟10.27] [JZOJ4270] 魔道研究 解题报告(动态开点+权值线段树上二分)
Description “我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力.”——<The Grimoire of Marisa>雾雨魔理 ...
随机推荐
- framework7 底部弹层popup js关闭方法
<div class="u-sd-btns"> <button>同意</button> <button class="popup ...
- k8s架构
master节点 k8s的集群由master和node组成,节点上运行着若干k8s服务. master节点之上运行着的后台服务有kube-apiserver .kube-scheduler.kube- ...
- win10 iis部署后 浏览目录报错 500.19
错误摘要HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配置数据无效.详细错误信息模块 IIS Web Core 通知 BeginReq ...
- 一文学会Rust?
Rust是什么 Rust 是一个系统编程语言,它注重三个方面:安全,速度和并发性. 特征: 1.没有垃圾回收机制,没有运行时,效率超过c++,直逼c语言 2.内存安全,并发安全,没有空指针 3.极其丰 ...
- Intellij Idea使用教程汇总篇
Java编程强大的工具IDEA使用教程及一些快捷键收藏如下: https://blog.csdn.net/fanrenxiang/article/details/80503490
- 求方程x1+x2+x3=15的整数解的数目
求方程x1+x2+x3=15的整数解的数目要求0≤x1≤5,0≤x2≤6,0≤x3≤7.解:令N为全体非负整数解(x1,x2,x3),A1为其中x1≥6的解:y1=x1-6≥0的解:A2为其中x2≥7 ...
- java 多线程并发问题总结
java 多线程并发主要通过关键字synchronized实现 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问 ...
- [DS+Algo] 006 两种简单排序及其代码实现
目录 1. 快速排序 QuickSort 1.1 步骤 1.2 性能分析 1.3 Python 代码示例 2. 归并排序 MergeSort 2.1 步骤 2.2 性能分析 2.3 Python 代码 ...
- java基础笔记(4)
二进制运算: &的应用:清零.得到指定位的数: |的应用:将指定位置取1: ^的应用:取反.保留原值:交换两个bian变量:A= A^B,B =A ^ B,A = A^B;(原理就是本身异或本 ...
- CDQ分治总结
\(CDQ\)分治小结 标签:知识点总结 阅读体验:https://zybuluo.com/Junlier/note/1326395 身为一个资深菜鸡 \(CDQ\)分治一开始学了一晚上,后来某一天又 ...