【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>雾雨魔理 ...
随机推荐
- ubuntu 16.04 配置ssl
Let's Encrypt 的服务相信很多人都知道了,我个人认为这是最好的免费 SSL 服务.下面内容即使如何在自己的网站上使用 Let's Encrypt 实现 SSL. 前提条件 自己拥有一个域名 ...
- TCP中SYN洪水攻击
在查看TCP标识位SYN时,顺便关注了一下SYN Flood,从网上查阅一些资料加以整理,SYN洪水攻击利用TCP三次握手. 1.SYN洪水介绍 当一个系统(客户端C)尝试和一个提供了服务的系统(服务 ...
- 应用安全 - 工具 - 浏览器 - IE浏览器 - 漏洞汇总
CVE-2014-6332 Date 2014.11 CVE-2016-0189 | MS16-051 Date 2016年初 CVE-2018-8174
- 关于Goroutine与Channel
关于Goroutine的原理 原理上的内容比较多,比如goroutine启动的时候要执行哪些相关的操作,一点一点的补充一下. channel的基本原理 channel是go语言中的特殊的机制,既可以同 ...
- python 并发编程 多进程 Process对象的其他属性方法 join 方法
一 Process对象的join方法 在主进程运行过程中如果想并发地执行其他的任务,我们可以开启子进程,此时主进程的任务与子进程的任务分两种情况 情况一: 在主进程的任务与子进程的任务彼此独立的情况下 ...
- 语言I—2019秋作业02
这个作业属于那个课程 这个作业要求在哪里 我在这个课程的目标是 这个作业在那个具体方面帮助我实现目标 参考文献 C语言程序设计I https://edu.cnblogs.com/campus/zswx ...
- [DS+Algo] 005 三种简单排序及其代码实现
目录 1. 冒泡排序 BubbleSort 1.1 算法描述 1.2 性能分析 1.3 Python 代码实现 2. 选择排序 SelectionSort 2.1 算法描述 2.2 选择排序的主要优点 ...
- Redis在Windows环境配置多实例多端口运行
Redis是一种跨平台NoSql内存数据库,这几年各大公司系统应用中非常多见,支持多种数据类型,可以持久化保存数据,很多公司直接拿来作为数据库使用. 相比于Memcached,Redis支持持久化保存 ...
- C#中的委托和事件(一)——delegate
前言 来说一说委托(delegate)和事件(event),本篇采取的形式是翻译微软Delegate的docs中的重要部分(不要问我为什么微软的docs有中文还要读英文,因为读中文感觉自己有阅读障碍- ...
- Python 入门之 内置模块 -- time模块
Python 入门之 内置模块 -- time模块 1.time模块 time翻译过来就是时间,这个模块是与时间相关的模块 import time # 内置模块 -- 标准库 (1)time.ti ...