【描述】

一个 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. UNITY_MATRIX_MVP和UnityObjectToClipPos

    在unity5.6以上版本中,shader中的UNITY_MATRIX_MVP将会被UnityObjectToClipPos替代,以后我们在写顶点函数时就是这样的 v2f vert(appdata v ...

  2. 【extjs6学习笔记】1.6 初始:本地化

    app.json中修改

  3. uvm_reg_predictor——寄存器模型(十七)

    这是寄存器模型类中唯一派生自uvm_component的类,我们的寄存器模式需要实时,以最接近的方式知道DUT中寄存器的变化,uvm_reg_predictor就是为这个而生的. // TITLE: ...

  4. C# 向服务器上传文件(客服端winform、服务端web)

    转载 首先写客服端,winform模拟一个post提交: /// <summary> /// 将本地文件上传到指定的服务器(HttpWebRequest方法) /// </summa ...

  5. Android(java)学习笔记133:Eclipse中的控制台不停报错Can't bind to local 8700 for debugger

    [DDMS] Can't bind to local 8600 for debugger 改成 Under Window -> Preferences -> Android -> D ...

  6. IO流_File类

        流(stream):流是一连串流动的数据(字节.字符),以先进先出的方式发送的信息的通道中.    输入流   数据从源数据源流入程序的过程称为输入流.可以理解为从源数据源读取数据到程序的过程 ...

  7. python解析xml实例

    如下,一个银行卡打标签后导出的数据 <?xml version="1.0" encoding="ISO-8859-1"?> <annotati ...

  8. 2018.4.16 Java多线程实现龟兔赛跑

    龟兔赛跑(通过多线程来实现 里面的具体方法) TT.java package com.lanqiao.demo3; /** * 乌龟 * @author Administrator * */ publ ...

  9. Paper: 《Bert》

    Bert: Bidirectional Encoder Representations from Transformers. 主要创新点:Masked LM 和 Next sentence predi ...

  10. Linux下如何通过命令检查网卡是否插上网线

    How To:Linux下如何通过命令检查网卡是否插上网线   主要工具为ethtool来检查,主要关注的字段为"Link detected",注意如下的输出,其中em4实际物理上 ...