【描述】

一个 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 黑白图的更多相关文章

  1. Shader中贴图知识汇总: 漫反射贴图、凹凸贴图、高光贴图、 AO贴图、环境贴图、 光照纹理及细节贴图

    原文过于冗余,精读后做了部分简化与测试实践,原文地址:http://www.j2megame.com/html/xwzx/ty/2571.html   http://www.cnblogs.com/z ...

  2. Java 图片转换为字符图 CharMaps (整理)

      /* * Java 图片转换成字符图 CharMaps (整理) * * 2016-1-2 深圳 南山平山村 曾剑锋 * * @(#)CharMaps.java 2014/1/16 * 1.这个一 ...

  3. 【转】Cocos2d-x 2.x CCSprite 灰白图的生成(利用shader设置)——2013-08-27 21

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=325 游戏中人物死掉后要把人物头 ...

  4. 矢量做图组件OTGisX的使用(类似Mapbase)

    一:组件添加到工具栏 要在应用程序中应用OTGisX控件,首先要把所下载的OTGisX组件添加到.Net工程中.并将其添加到工具箱托盘中.添加方式为:在工具箱上单击右键,选择“选择项”,会出现“选择工 ...

  5. BMP彩色转成黑色二值图

    一天半把彩色bmp转成黑白了. 原理是: 第一步:读出位图数据的偏移位置:即第11个字节,用fseek即可. 然后将偏移位置之前的数据全部写入新的bmp图中. 第二步:用fseek移到位图数据这前,判 ...

  6. Qt生成灰度图(转载)

    Qt生成灰度图(转载)   项目中用到大量基础图像处理知识,其中灰度图的生成是很重要的一环. 先补充一些基础知识: ------------------------------------------ ...

  7. S0.4 二值图与阈值化

    目录 二值图的定义 二值图的应用 阈值化 二值化/阈值化方法 1,无脑简单判断 opencv3函数threshold()实现 2,Otsu算法(大律法或最大类间方差法) OpenCV3 纯代码实现大津 ...

  8. (转)Unity3D 游戏贴图(法线贴图,漫反射贴图,高光贴图)

    原帖网址http://www.u3dpro.com/read.php?tid=207  感谢jdk900网友的辛苦编写 我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图 ...

  9. 【Qt开发】QImage设置为8-bit灰度图

    项目中用到大量基础图像处理知识,其中灰度图的生成是很重要的一环. 先补充一些基础知识: -------------------------------------------------------- ...

随机推荐

  1. Sqoop基础学习(1)

    1. Sqoop的导入过程 在开始导入之前,Sqoop会通过JDBC来获得所需要的数据库元数据 1.导入表的列名.数据类型等: 2.接着这些数据库的数据类型(varchar.number等)会把映射成 ...

  2. 3D OpenGL ES

    什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库. 为桌面版本OpenGL 的一个子集. ...

  3. Android商城开发系列(七)—— 使用RecyclerView展示首页数据

    前面我们讲到了使用OkHttp请求网络和FastJson解析数据了,接下来我们就开始把获取到的数据通过数据适配器展示在页面上了.Adapter是用来帮助填充数据的中间桥梁,简单点说就是:将各种数据以合 ...

  4. 打印机 Microsoft Print to PDF 所需的驱动程序 Microsoft Print To PDF 未知。登录之前,请与管理员联系,安装驱动程序。

    这个问题发生后,我觉得很疑惑,因为服务器上确定没有安装打印机.那么打印机是从哪里来的呢? 通过百度搜索,发现网上的一个帖子解答了我的疑惑.原帖地址:http://blog.chinaunix.net/ ...

  5. JavaScript实现页面到滚动到指定位置执行某些操作

    比如 页面中 某个DOM, 希望点击按钮后页面直接跳转到 这个DOM所在的位置, 1. 获取DOM离屏幕的高度 var hTop = $('#box').offset().top; $('body,h ...

  6. python3从尾到头打印链表

    题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 方法一:通过栈实现 # -*- coding:utf-8 -*- # class ListNode: # def __ini ...

  7. 自实现RPC调用

    服务提供者 服务接口: public interface HelloService { public String sayHello(String name); } 服务实现类: public cla ...

  8. 面向对象OONo.3单元总结

    一,JML语言 1)JML理论基础:JML是一类语言,用来描述一个方法或一个类的功能.以及这个类在实现这个功能时需要的条件.可能改变的全局变量.以及由于条件问题不能实现功能时这个方法或类的行为,具有明 ...

  9. LINQ与反射

    string file = @"C:\Windows\winsxs\x86_netfx35linq-system.core_31bf3856ad364e35_6.1.7601.17514_n ...

  10. CV做直方图的比较说明图形越相似性

    #include "opencv/cv.hpp" #include "opencv2/objdetect/objdetect.hpp" #include &qu ...