NOIP2017 7.17模拟 Minimum (最短路+最小生成树)
2017-07-18 08:41
351 查看
题目描述:
给出一幅由 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
【数据范围】
对 30% 的输入数据 :1≤n≤10,1≤m≤20;
对 100% 的输入数据 :1≤n≤100000,1≤m≤200000,1≤z≤1000000000 。
题意:将所有白点和黑点通过在最短路上的路径连接,求最小代价,无解的情况是存在白点与黑点无法连通。通过分析我们可以发现,有解的情况可以分为两个问题考虑:
1、求最短路;
2.并找到在最短路上的边;
3、通过这些边跑一边最小生成树,统计边权之和。
对于第一个问题,因为是要求任意一个白点到任意一个黑点的距离,我们可以想到建一个超级点,由它向每一个黑点连一条边权为0的有向边,然后由这个超级点跑一次最短路(迪杰斯特拉或spfa),就行了;
对于第二个问题,由最短路的更新方法
我们可以想到,遍历每条边,满足dis[edge[i].start]==dis[edge[i].end+edge[i[.val那么这条边一定是最短路上的边,由此我们可以找到所有最短路上的边
对于第三个问题,裸的最小生成树,在此就不赘述了;
给出一幅由 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
【数据范围】
对 30% 的输入数据 :1≤n≤10,1≤m≤20;
对 100% 的输入数据 :1≤n≤100000,1≤m≤200000,1≤z≤1000000000 。
题意:将所有白点和黑点通过在最短路上的路径连接,求最小代价,无解的情况是存在白点与黑点无法连通。通过分析我们可以发现,有解的情况可以分为两个问题考虑:
1、求最短路;
2.并找到在最短路上的边;
3、通过这些边跑一边最小生成树,统计边权之和。
对于第一个问题,因为是要求任意一个白点到任意一个黑点的距离,我们可以想到建一个超级点,由它向每一个黑点连一条边权为0的有向边,然后由这个超级点跑一次最短路(迪杰斯特拉或spfa),就行了;
对于第二个问题,由最短路的更新方法
if(dis[a]+val[i]<dis[to[i]]) dis[to[i]]=dis[a]+val[i];
我们可以想到,遍历每条边,满足dis[edge[i].start]==dis[edge[i].end+edge[i[.val那么这条边一定是最短路上的边,由此我们可以找到所有最短路上的边
对于第三个问题,裸的最小生成树,在此就不赘述了;
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #include<string> #include<iomanip> #include<iostream> #include<cctype> #include<queue> using namespace std; int n,m,tot,sup,cnt,len,fa[100005],next[500010],first[100005],to[500010]; long long dis[100005]; long long val[500010]; bool black[100005],ok=true; //--------------------- priority_queue< pair<int,int> > que; pair<int,int> temp; //--------------------- struct node { int st,end; long long val; }a[400010]; bool cmp(const node&a,const node&b) { return a.val<b.val; } //--------------------- inline long long Readint() { long long i=0,f=1; char ch; for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar()); if(ch=='-') f=-1; for(;ch>='0'&&ch<='9';ch=getchar()) i=(i<<1)+(i<<3)+ch-'0'; return i*f; } //--------------------- inline void add(int x,int y,long long z) { next[++tot]=first[x]; first[x]=tot; to[tot]=y; val[tot]=z; } //--------------------- inline void djstra(int root) { dis[root]=0; temp.first=0; temp.second=root; que.push(temp); while(!que.empty()){ temp=que.top(); que.pop(); int a=temp.second; for(int i=first[a];i;i=next[i]){ if(dis[a]+val[i]<dis[to[i]]){ dis[to[i]]=dis[a]+val[i]; pair<int,int> s; s.first=-dis[to[i]]; s.second=to[i]; que.push(s); } } } } //--------------------- inline int find(int x) { if(x==fa[x]) return x; fa[x]=find(fa[x]); return fa[x]; } //--------------------- int main() { freopen("minimum.in","r",stdin); n=Readint(),m=Readint(); memset(first,0,sizeof(first)); for(int i=0;i<=n;i++) fa[i]=i; for(int i=0;i<=n;i++) dis[i]=1e16+7; for(int i=1;i<=n;i++){ black[i]=Readint(); if(black[i]) add(sup,i,0); } for(int i=1;i<=m;i++){ int x,y; long long z; x=Readint(),y=Readint(),z=Readint(); add(x,y,z),add(y,x,z); } djstra(sup); for(int i=1;i<=n;i++) if(dis[i]==1e16+7) ok=false; if(!ok){ cout<<"impossible"<<endl; return 0; } for(int i=1;i<=n;i++){ for(int p=first[i];p;p=next[p]){ if(dis[to[p]]==val[p]+dis[i]){ a[++len].st=i,a[len].end=to[p],a[len].val=val[p]; } } } long long ans=0; sort(a+1,a+1+len,cmp); for(int i=1;i<=len;i++){ int fx=find(a[i].st),fy=find(a[i].end); if(fx!=fy){ fa[fx]=fy; ans+=a[i].val; cnt++; } if(cnt==n-1) break; } cout<<ans<<endl; return 0; }
相关文章推荐
- 【NOIP2017提高A组模拟10.8】Star Way To Heaven(欧几里得距离最小生成树Prim做法)
- 【GDOI2017第二轮模拟day1】公路建设(克鲁斯卡尔最小生成树+线段树+归并)
- 最小生成树&最短路模板
- Union Find 在 最小生成树(Minimum Spanning Tree)中的实现
- HDU 4408 Minimum Spanning Tree(最小生成树计数)
- 第十三章 ALDS1_12_A:Minimum Spanning Tree 最小生成树
- JZOJ.5287【NOIP2017模拟8.16】最短路
- 最小生成树(minimum spanning tree)问题的两种解法
- 2017.4.3 机房测试 (并查集,最短路,拓扑排序,最小生成树)
- 说说最小生成树(Minimum Spanning Tree)
- 【基础算法练习】【最短路+图的遍历+最小生成树】水题 C+ E+ F-----AC题
- 图论小结(一)包括一些最短路,最小生成树,差分约束,欧拉回路,的经典题和变种题。强连通,双连通,割点割桥的应用。二分匹配,KM,支配集,独立集,还有2-SAT。
- Minimum Transport Cost hdu 点权和边权的最短路+输出字典序最小的路径
- Geeks : Kruskal’s Minimum Spanning Tree Algorithm 最小生成树
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- 无向图最小生成树、次小生成树,最短路模板
- poj2253 Frogger(最短路变型或者最小生成树)
- 最小生成树 (Minimum Spanning Tree,MST) --- Prim算法
- POJ 1797 Heavy Transportation(最小生成树或最短路)
- BZOJ4144 [AMPPZ2014]Petrol 【最短路 + 最小生成树】