【描述】

一个 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. 数据结构-List接口-LinkedList类-Set接口-HashSet类-Collection总结

    一.数据结构:4种--<需补充> 1.堆栈结构:     特点:LIFO(后进先出);栈的入口/出口都在顶端位置;压栈就是存元素/弹栈就是取元素;     代表类:Stack;     其 ...

  2. Swing---WindowConstants

    Java桌面开发过程中,很多人都写过类似下面的代码. import javax.swing.JFrame; public class SimpleFrame { public static void ...

  3. 排序算法C语言实现

    大学有一门课程叫做数据结构,严蔚敏的课本,其中详细介绍了集中经典的排序算法,学习复习反复几次,但是直到现在仍然只记得名字了,所以想记录下来,随时复习直至牢记于心.经常面试的朋友知道,排序算法在面试中出 ...

  4. 正确配置Nginx+PHP

    对很多人而言,配置Nginx+PHP无外乎就是搜索一篇教程,然后拷贝粘贴.听上去似乎也没什么问题,可惜实际上网络上很多资料本身年久失修,漏洞百出,如果大家不求甚解,一味的拷贝粘贴,早晚有一天会为此付出 ...

  5. destoon登录后跳转到指定网址

    打开module\member\register.inc.php文件搜索:<input type="hidden" name="forward" valu ...

  6. python之道08

    1.有如下文件,a1.txt,里面的内容为: 某某是最好的学校, 全心全意为学生服务, 只为学生未来,不为牟利. 我说的都是真的.哈哈 分别完成以下的功能: a,将原文件全部读出来并打印. 答案 f ...

  7. Linux学习日记:第二天

    今天学习vi编辑命令: root@ubuntu:vi hello.java 使用到的命令: 插入命令: a 和 i:在当前光标前或后插入文本(A 和 I 分别在当前行行末或行首插入文本):  o 和  ...

  8. maven,gradle本地缓存位置

    gradle: 配置系统环境变量GRADLE_USER_HOME即可,值为缓存位置. maven: 修改settings文件:maven的home路径下的conf文件夹下的settings.xml 对 ...

  9. NOIP2013 乌龟棋

    描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点 ...

  10. 网络流(一)——Edmonds Karp算法

    首先是一些关于网络流的术语: 源点:即图的起点. 汇点:即图的终点. 容量:有向边(u,v)允许通过的最大流量. 增广路:一条合法的从源点流向汇点的路径. 网络流问题是在图上进行解决的,我们通常可以将 ...