2016国庆集训day3-minimum.cpp
2016-10-05 21:05
363 查看
Description
给出一幅由 n 个点 m 条边构成的无向带权图。
其中有些点是黑点,另外点是白点。
现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个,可以选取其中任意一个) , 我们想要使得花费的代价最小。请问这个最小代价是多少?
注意:最后选出的边保证每个白点到黑点的距离任然是最短距离。
Input Format
第一行两个整数 n,m
第二行 n 个整数,0 表示白点,1 表示黑点
接下来 m 行,每行三个整数 x,y,z,表示一条连接 x 和 y 点,权值为 z 的边。
Output Format
如果无解,输出 impossible;
否则,输出最小代价
Sample Input
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
Sample Output
5
Hint
选 2、4、6 三条边
• 对于 30% 的数据,1 ≤ n ≤ 10,1 ≤ m ≤ 20。
• 对于 100% 的数据,1 ≤ n ≤ 10 5 ,1 ≤ m ≤ 2 × 10 5 ,1 ≤ z ≤ 10 9 。
这题看完题,就知道是图论,结合数据的特点:边不超过点的2倍——稀疏图。所以应该考虑到SPFA算法。
每个白点都连到最近的黑点,所以,黑点与黑点间的边没有用。
抽象来看,就是所以的白点到一个整体(黑点的集合)的最短距离之和。
考试完学会了“缩点”——不是很明白缩点的应用,但知道它简化问题,有待研究。
我把所有的黑点直接替代成一个点“0”,这样问题转化成了:
所有白点的0点的dist和;
SPFA求完所有最短路后,我们在从“0”出发往回dfs,找到最短路径上的边,即在SPFA中“d[v]>d[u]+v[u,v]”的v[u,v];
一条边可能被多次经过,我们dfs可能会重复把它们选出来,因此,再来一次
最小生成树Kruskal找边。
如果我们求的边权和ans==0,那么说明一条边也找不到,那么“impossible”。
有一组数据:
Input
5 4
1 0 0 0 1
1 2 3
2 3 2
3 4 1
4 5 4
Output
8
情况为点有两条以上的最短路径通向“0”,题目要求“与白点最近的黑点”,所以这个数据挂了,我把非直接连向0的边再增加权值,保证可以走“最近的路”,求值是再判断减去;
以下codes:
增加权值的方法正确性有待研究!
给出一幅由 n 个点 m 条边构成的无向带权图。
其中有些点是黑点,另外点是白点。
现在每个白点都要与他距离最近的黑点通过最短路连接(如果有很多个,可以选取其中任意一个) , 我们想要使得花费的代价最小。请问这个最小代价是多少?
注意:最后选出的边保证每个白点到黑点的距离任然是最短距离。
Input Format
第一行两个整数 n,m
第二行 n 个整数,0 表示白点,1 表示黑点
接下来 m 行,每行三个整数 x,y,z,表示一条连接 x 和 y 点,权值为 z 的边。
Output Format
如果无解,输出 impossible;
否则,输出最小代价
Sample Input
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
Sample Output
5
Hint
选 2、4、6 三条边
• 对于 30% 的数据,1 ≤ n ≤ 10,1 ≤ m ≤ 20。
• 对于 100% 的数据,1 ≤ n ≤ 10 5 ,1 ≤ m ≤ 2 × 10 5 ,1 ≤ z ≤ 10 9 。
这题看完题,就知道是图论,结合数据的特点:边不超过点的2倍——稀疏图。所以应该考虑到SPFA算法。
每个白点都连到最近的黑点,所以,黑点与黑点间的边没有用。
抽象来看,就是所以的白点到一个整体(黑点的集合)的最短距离之和。
考试完学会了“缩点”——不是很明白缩点的应用,但知道它简化问题,有待研究。
我把所有的黑点直接替代成一个点“0”,这样问题转化成了:
所有白点的0点的dist和;
SPFA求完所有最短路后,我们在从“0”出发往回dfs,找到最短路径上的边,即在SPFA中“d[v]>d[u]+v[u,v]”的v[u,v];
一条边可能被多次经过,我们dfs可能会重复把它们选出来,因此,再来一次
最小生成树Kruskal找边。
如果我们求的边权和ans==0,那么说明一条边也找不到,那么“impossible”。
有一组数据:
Input
5 4
1 0 0 0 1
1 2 3
2 3 2
3 4 1
4 5 4
Output
8
情况为点有两条以上的最短路径通向“0”,题目要求“与白点最近的黑点”,所以这个数据挂了,我把非直接连向0的边再增加权值,保证可以走“最近的路”,求值是再判断减去;
以下codes:
#include <algorithm> #include <cstdio> #include <cmath> #include <vector> #include <stack> #include <queue> #include <cstring> #define maxn 100005 using namespace std; struct edge{ int to,next,f; long long v; }e[400005],E[400005]; int last[maxn],fa[maxn],color[maxn]; bool vis[maxn]; int tot,tot1,n,m,cnt; bool flag; long long ans,d[maxn]; int cur; bool cmp (const edge x,const edge y) { return x.v<y.v; } int get(int x) { if (fa[x]==x) return x; long long y=get(fa[x]); fa[x]=y; return y; } void Kruskal() { sort(E+1,E+1+tot1,cmp); for (int i=1;i<=tot1;i++) { cur=0; int fx=get(E[i].f); int fy=get(E[i].to); if (fx!=fy) { fa[fy]=fx; if (E[i].f!=0&&E[i].to!=0)cur=-2; ans+=E[i].v+cur; } } } void find(int u) { for (int i=last[u];i;i=e[i].next) { int v=e[i].to; int k=e[i].v; if (d[v]==d[u]+k) { find(v); tot1++; E[tot1].f=u; E[tot1].to=v; E[tot1].v=k; } } return ; } void spfa() { queue<int>q; memset(vis,0,sizeof(vis)); for (int i=0;i<=n;i++) d[i]=9999999999999; d[0]=0; q.push(0); vis[0]=1; while (!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for (int i=last[u];i;i=e[i].next) { int v=e[i].to; int k=e[i].v; if (d[v]>d[u]+k) { d[v]=d[u]+k; if (vis[v]==0) { vis[v]=1; q.push(v); } } } } } void add(int x,int y,int z) { fa[y]=y; tot++; e[tot].v=z; e[tot].to=y; e[tot].next=last[x]; last[x]=tot; } int main() { tot=0; tot1=0; scanf("%d%d",&n,&m); flag=true; for (int i=1;i<=n;i++) scanf("%d",&color[i]); for (int i=1;i<=m;i++) { int x,y,z; cur=0; scanf("%d%d%d",&x,&y,&z); if (color[x]==0 || color[y]==0) { if (color[x]==1)x=0; if (color[y]==1)y=0; if (x!=0&&y!=0)cur=2; add(x,y,z+cur); add(y,x,z+cur); } } spfa(); find(0); Kruskal(); if (ans==0) printf("impossible"); else printf("%lld",ans); return 0; }
增加权值的方法正确性有待研究!
相关文章推荐
- AYIT2016省赛集训第五周 K - Minimum Sum LCM(分解质因子)
- 2016信烨国庆集训总结
- xor 2016 国庆集训day3
- 2017国庆郑州集训游记Day3
- 2017国庆郑州集训游记Day3
- 串 2016Vijos省选集训 day3[AC自动机]
- 国庆郑州集训day3:数据结构
- 2016暑期集训10 C吴传之火烧连营
- {题解}[jzoj4841]【NOIP2016提高A组集训第4场11.1】平衡的子集
- 2016暑期集训16A强迫症
- BZOJ4730 UOJ#266【清华集训2016】Alice和Bob又在玩游戏
- JZOJ4899. 【NOIP2016提高A组集训第17场11.16】雪之国度
- 2016 寒假集训有感
- 省队集训 Day3 陈姚班
- 2016国庆清北Day2T1
- 【泉州一中国庆集训day6】String
- UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】
- 国庆七天乐 Day3
- JZOJ4860【NOIP2016提高A组集训第7场11.4】分解数
- JZOJ4866【NOIP2016提高A组集训第8场11.5】禅与园林艺术