【NOIP2015模拟10.22】最小代价
来源:互联网 发布:ecmall微信商城源码 编辑:程序博客网 时间:2024/05/21 17:26
前言
本来在比赛上就想到最小生成树了,但不相信这道题那么简单,然后就没有然后了。。。
题目
给出一幅由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;}
1 0
- 【NOIP2015模拟10.22】最小代价
- 【NOIP2015 10.22模拟】总结
- 最小代价
- 最小代价;;;;
- 最小代价
- 最小代价
- NOIP2015模拟1
- NOIP2015模拟3
- NOIP2015模拟2
- NOIP2015模拟4
- 【NOIP2015 模拟9.12】平方和
- 【NOIP2015模拟10.20】平均数
- 【NOIP2015模拟10.20】ACM
- 【NOIP2015 模拟10.27】总结
- 【NOIP2015 10.29模拟】总结
- 【NOIP2015 10.28模拟】总结
- 【NOIP2015 11.3模拟】总结
- NOIP2015模拟11.5总结
- window下eclipse配制hadoop插件 (四)
- 李白打酒
- Opera安装详解
- Java抽象类与接口的区别
- 某公司笔试题
- 【NOIP2015模拟10.22】最小代价
- 第九周项目2:深复制体验(2)
- 设计模式之行为类模式
- adroid线程池的运用
- 匈牙利算法详解
- 奇怪的电梯
- sublime text编辑器html页面预览
- RBAC权限
- POJ 2488 A Knight's Journey