SDOJ 3742 黑白图
【描述】
一个 n 个点 m 条边构成的无向带权图。由一些黑点与白点构成 树现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个,可以选 取其中任意一个),我们想要使得花费的代价最小。请问这个最小代价是多少? 注意:最后选出的边保证每个白点到黑点的距离任然是最短距离。
【输入】
第一行两个整数 n,m; 第二行 n 个整数,0 表示白点,1 表示黑点; 接下来 m 行,每行三个整数 x,y,z,表示一条连接 x 和 y 点,权值为 z 的边。
【输出】
如果无解,输出 impossible; 否则,输出最小代价。
【输入样例】
5 7 0 1 0 1 0 1 2 11 1 3 1 1 5 17 2 3 1 3 5 18 4 5 3 2 4 5
【输出样例】
5
【样例说明】
选 2、4、6 三条边;
【数据范围】
对 30%的输入数据 : 1≤n≤10, 1≤m≤20; 对 100%的输入数据 :1≤n≤100000,1≤m≤200000,1≤z≤1000000000
------------------------------------------------------------------------------------------------
这道题有两个关键点,一是距离最近的黑点,一是价值最小。
对于距离最近,我们可以建立一个超级汇点,汇点用零边连接每个黑点,然后从汇点开始跑最短路。
因为汇点和黑点之间权值为0,所以汇点与白点之间跑出来的最短路是白点和黑点之间的最短路。
对于第二点,价值最小,我们已经得到了最短路径图、确定了距离白点最近的黑点,所以可以跑一个最小生成树,在确保图连通的情况下得到最小价值。
注:形成的最小生成树上的边不一定是白点到黑点最短距离的边,但可以肯定这个黑点是最优的,而且我们关注的是最小价值。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define N 200100
#define INF 0x3f
using namespace std;
long long n,m,ans=;
bool vis[N];
long long dis[N];
long long fa[N];
struct node
{
long long u,v,w,nxt;
}e[N*],d[N*];
long long first[N],cnt,tot;
void ade(long long u,long long v,long long w)
{
e[++cnt].nxt=first[u]; first[u]=cnt;
e[cnt].u=u; e[cnt].v=v; e[cnt].w=w;
}
queue<long long>q;
void spfa(long long x)
{
memset(dis,0x3f,sizeof(dis));
memset(vis,true,sizeof(vis));
q.push(x);
dis[x]=;
while(!q.empty())
{
long long u=q.front(); q.pop();
vis[u]=true;
for(long long i=first[u];i;i=e[i].nxt)
{
long long v=e[i].v;
if(dis[v]>dis[u]+e[i].w)
{
dis[v]=dis[u]+e[i].w;
if(vis[v]==true)
{
q.push(v);
vis[v]=false;
}
}
}
}
}
inline bool cmp(node a,node b)
{
return a.w<b.w;
}
long long la(long long x)
{
if(fa[x]!=x) fa[x]=la(fa[x]);
return fa[x];
}
void kruskal()
{
sort(e+,e+tot+,cmp);
for(long long i=;i<=n;i++) fa[i]=i;
long long cnnt=n;
for(long long i=;i<=tot;i++)
{
if(!cnnt) break;
long long x=la(d[i].u);
long long y=la(d[i].v);
if(x==y) continue;
fa[x]=y;
ans+=d[i].w;
--cnnt;
}
}
int main()
{
scanf("%lld%lld",&n,&m);
for(long long i=,x;i<=n;i++)
{
scanf("%lld",&x);
if(x==) ade(n+,i,);//ade(i,n+1,0);//建立汇点
}
for(long long i=;i<=m;i++)
{
long long x,y,z;
scanf("%lld%lld%lld",&x,&y,&z);
ade(x,y,z);ade(y,x,z);
}
spfa(n+);
// for(long long i=1;i<=n;i++) cout<<dis[i]<<" ";
// cout<<endl;
bool pu=;
for(long long i=;i<=n;i++)
{
if(dis[i]==INF) pu=;
for(long long j=first[i];j;j=e[j].nxt)//!!!!!!!!建立新最短路图
if(dis[e[j].v]==dis[i]+e[j].w)
d[++tot].u=i,d[tot].v=e[j].v,d[tot].w=e[j].w;
}
// for(long long i=1;i<=tot;i++)
// cout<<d[i].u<<" "<<d[i].v<<" "<<d[i].w<<endl;
// cout<<endl;
if(pu==)
{
printf("impossible\n");
return ;
}
kruskal();
if(ans==)
{
printf("impossible\n"); return ;
}
printf("%lld\n",ans);
return ;
}
SDOJ 3742 黑白图的更多相关文章
- Shader中贴图知识汇总: 漫反射贴图、凹凸贴图、高光贴图、 AO贴图、环境贴图、 光照纹理及细节贴图
原文过于冗余,精读后做了部分简化与测试实践,原文地址:http://www.j2megame.com/html/xwzx/ty/2571.html http://www.cnblogs.com/z ...
- Java 图片转换为字符图 CharMaps (整理)
/* * Java 图片转换成字符图 CharMaps (整理) * * 2016-1-2 深圳 南山平山村 曾剑锋 * * @(#)CharMaps.java 2014/1/16 * 1.这个一 ...
- 【转】Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)——2013-08-27 21
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=325 游戏中人物死掉后要把人物头 ...
- 矢量做图组件OTGisX的使用(类似Mapbase)
一:组件添加到工具栏 要在应用程序中应用OTGisX控件,首先要把所下载的OTGisX组件添加到.Net工程中.并将其添加到工具箱托盘中.添加方式为:在工具箱上单击右键,选择“选择项”,会出现“选择工 ...
- BMP彩色转成黑色二值图
一天半把彩色bmp转成黑白了. 原理是: 第一步:读出位图数据的偏移位置:即第11个字节,用fseek即可. 然后将偏移位置之前的数据全部写入新的bmp图中. 第二步:用fseek移到位图数据这前,判 ...
- Qt生成灰度图(转载)
Qt生成灰度图(转载) 项目中用到大量基础图像处理知识,其中灰度图的生成是很重要的一环. 先补充一些基础知识: ------------------------------------------ ...
- S0.4 二值图与阈值化
目录 二值图的定义 二值图的应用 阈值化 二值化/阈值化方法 1,无脑简单判断 opencv3函数threshold()实现 2,Otsu算法(大律法或最大类间方差法) OpenCV3 纯代码实现大津 ...
- (转)Unity3D 游戏贴图(法线贴图,漫反射贴图,高光贴图)
原帖网址http://www.u3dpro.com/read.php?tid=207 感谢jdk900网友的辛苦编写 我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图 ...
- 【Qt开发】QImage设置为8-bit灰度图
项目中用到大量基础图像处理知识,其中灰度图的生成是很重要的一环. 先补充一些基础知识: -------------------------------------------------------- ...
随机推荐
- linux 查看dd进度
Linux下显示dd命令的进度: dd if=/dev/zero of=/tmp/zero.img bs=10M count=100000 想要查看上面的dd命令的执行进度,可以使用下面几种方法: 比 ...
- Centos安装iptables防火墙
一.安装说明: 1.因为centos7.0及以上版本就默认安装了firewall防火墙,但有时候根据项目实际所需,服务器上还是需要安装iptables,以下就是具体的安装步骤: 2.因阿里云在服务器外 ...
- PHP的加解密:如何安装ioncube扩展?
一.下载loader-wizard.php(支持php5.3.php5.4.php5.5.php5.6版本) ioncube提供了一个安装的向导程序,可以非常方便的帮助检测php的运行环境,自动给出提 ...
- cookie和session是否可以保存对象
session看了一下,是可以保存对象的.语法很普通,但是cookie的话本身是只能保存string类型的信息的,这就需要先序列化,然后接收的页面反序列化后形成对象调用,为了防止乱码,需要在数据传输的 ...
- Codeforces Round #320 (Div. 1) [Bayan Thanks-Round] B "Or" Game (贪心)
首先应该保证二进制最高位尽量高,而位数最高的数乘x以后位数任然是最高的,所以一定一个数是连续k次乘x. 当出现多个最高位的相同的数就枚举一下,先预处理一下前缀后缀即可. #include<bit ...
- 单核CPU并发与非并发测试
多线程运行程序的目的一般是提高程序运行效率并且能够提高硬件的利用率比如多核CPU,但是如果我们只有单核CPU并发运行程序会怎样呢? 我以两个环境作为对比: 环境A(我本机8c) 环境B(我的云服务器1 ...
- appium---启动app
自动化测试是测试人员必备的一项技能,所谓的自动化就是通过代码完成了手工的操作,今天就总结下如何通过python启动app 环境条件 1.安装python:下载地址 2.安装JDK:下载地址 3.安装A ...
- 关于List的remove方法我遇到的坑
结果是下标越界异常,原因是remove方法的参数不是value,而是index 唉~~~ 年少轻狂啊
- mtDNA|ctDNA|cpDNA|
5.9细胞器基因组是编码细胞器蛋白质的环状DNA分子 细胞器中除真核细胞线粒体DNA(mtDNA)是线性的外,都是环状分子,比如叶绿体DNA(ctDNA,cpDNA).因为单个细胞器有几套不同拷贝的细 ...
- c#和Java中的接口
使用场景: 在c#和Java中: 1.接口可以实现“多继承”(多实现),一个类只能继承自一个父类,但是可以实现多个接口. 2.接口解决了不同类型之间的多态问题,比如鱼与船不是同一类型,但是都能在水里“ ...