【Kruskal+贪心思想】BZOJ3624-[Apio2008]免费道路
国庆万岁!!!!!
【题目大意】
给定一张无向图,有两种边的类型为0和1。求一个最小生成树使得边0有k条。
【思路】
跑两次Kruskal。
第一次的时候优先选择边1,然后判断有哪些边0还不能连通,那么这些边0是必须要选取的。如果必须要选的边0大于k,那么直接输出无解。
第二次的时候先合并那么必须要选取的边0,然后在剩下的边0中左右还没有连通的里选取。如果把所有都选上了之后边0的数量还是没有到k,那么直接输出无解。
截下来按照普通Kruskal的方法把边1合并掉。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN=+;
const int MAXM=+;
struct Edge
{
int u,v;
}edge[MAXM];
int n,m,k;
int vis[MAXM];
int L,R;
int fa[MAXN],h[MAXN];
vector<int> mustchoose; void initset(){for (int i=;i<=n;i++) fa[i]=i,h[i]=;} int find(int x)
{
int r=x;
while (fa[r]!=r) r=fa[r];
while (fa[x]!=r)
{
int tmp=fa[x];
fa[x]=r;
x=fa[x];
}
return r;
} void unionset(int a,int b)
{
if (h[a]>=h[b])
{
fa[b]=a;
if (h[a]==h[b]) h[a]++;
}
else fa[a]=b;
} void init()
{
scanf("%d%d%d",&n,&m,&k);
L=,R=m+;
for (int i=;i<=m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
if (c) edge[++L]=(Edge){u,v};
else edge[--R]=(Edge){u,v};
}
} void solve()
{
int t=;
initset();
for (int i=;i<=m;i++)
{
int fa=find(edge[i].u),fb=find(edge[i].v);
if (fa!=fb)
{
unionset(fa,fb);
if (i>=R)
{
vis[i]=;
t++;
mustchoose.push_back(i);
}
}
}
if (t>k)
{
puts("no solution");
return;
}
// 找出必须要选择的鹅卵石路 initset();
for (int i=;i<mustchoose.size();i++)
{
int fa=find(edge[mustchoose[i]].u),fb=find(edge[mustchoose[i]].v);
unionset(fa,fb);
}
for (int i=R;i<=m;i++)
if (t<k && !vis[i])
{
int fa=find(edge[i].u),fb=find(edge[i].v);
if (fa!=fb)
{
unionset(fa,fb);
vis[i]=;
t++;
}
}
if (t<k)
{
puts("no solution");
return;
}
//先选择必须要的鹅卵石路,然后再用其他鹅卵石路填充 for (int i=;i<=L;i++)
{
int fa=find(edge[i].u),fb=find(edge[i].v);
if (fa!=fb)
{
unionset(fa,fb);
vis[i]=;
}
}
for (int i=;i<=L;i++) if (vis[i]) printf("%d %d %d\n",edge[i].u,edge[i].v,);
for (int i=R;i<=m;i++) if (vis[i]) printf("%d %d %d\n",edge[i].u,edge[i].v,);
} int main()
{
init();
solve();
}
【Kruskal+贪心思想】BZOJ3624-[Apio2008]免费道路的更多相关文章
- [BZOJ3624][Apio2008]免费道路
[BZOJ3624][Apio2008]免费道路 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入”. 题解 第一步,先尽量加入 c = 1 的边,若未形成一个连通块,则得到必须加入 ...
- BZOJ3624: [Apio2008]免费道路(最小生成树)
题意 题目链接 Sol 首先答案一定是一棵树 这棵树上有一些0边是必须要选的,我们先把他们找出来,如果数量$\geqslant k$显然无解 再考虑继续往里面加0的边,判断能否加到k条即可 具体做法是 ...
- Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...
- BZOJ 3624: [Apio2008]免费道路
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1201 Solved: ...
- bzoj 3624: [Apio2008]免费道路 生成树的构造
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 111 Solved: 4 ...
- 题解 Luogu P3623 [APIO2008]免费道路
[APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...
- [Apio2008]免费道路[Kruscal]
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1292 Solved: ...
- P3623 [APIO2008]免费道路
3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special Judge Submit: 2143 Solved: 88 ...
- [APIO2008]免费道路
[APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...
随机推荐
- 22、WebDriver
什么是WebDriver?1.Webdriver(Selenium2)是一种用于Web应用程序的自动测试工具:2.它提供了一套友好的API:3.Webdriver完全就是一套类库,不依赖任何测试框架, ...
- JWT机制了解
JWT简介 JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑(Compact)且自包含(Self-contained)的方式,用于在各方之间以JSON对象安 ...
- html5手机Web单页应用实践--起点移动阅读
一开始以hybrid形式做了一个android的小说阅读客户端,叫4G阅读.而后由于业务需求,要迅速实现纯手机html5 版的,所以就直接在原先客户端内内嵌的网页进行改版,快速实现以后在优化的过程中发 ...
- 在wamp下增加多版本的PHP(PHP5.3,PHP5.4,PHP5.5)支持
1.安装WAMPServer 根据自己的操作系统选择相应的WAMP版本,我这里选择WAMPSERVER-32 BITS & PHP 5.5-2.5, 双击安装,选择安装目录即可,超级简单.根据 ...
- GSON转换日期数据为特定的JSON数据
通过JSON传递数据的时候经常需要传递日期,Java中可以通过GSON将日期转换为特定格式的JSON数据. 1.普通的GSON转换日期 public void query(HttpServletReq ...
- Mysql中的primary key 与auto_increment
mysql> create table cc(id int auto_increment); ERROR (): Incorrect table definition; there can be ...
- 42.Trapping Rain Water---dp,stack,两指针
题目链接:https://leetcode.com/problems/trapping-rain-water/description/ 题目大意:与84题做比较,在直方图中计算其蓄水能力.例子如下: ...
- 【并行计算】基于OpenMP的并行编程
我们目前的计算机都是基于冯偌伊曼结构的,在MIMD作为主要研究对象的系统中,分为两种类型:共享内存系统和分布式内存系统,之前我们介绍的基于MPI方式的并行计算编程是属于分布式内存系统的方式,现在我们研 ...
- C++ 模版的优点和缺点
优点: 1. 灵活性, 可重用性和可扩展性; 2. 可以大大减少开发时间,模板可以把用同一个算法去适用于不同类型数据,在编译时确定具体的数据类型; 3. 模版模拟多态要比C++类继承实现多态效率要高, ...
- 集合框架之Map学习
Map接口的实现类有HashTable.HashMap.TreeMap等,文章学习整理了“ Map和HashMap的使用方法”. /** * Map和HashMap的使用方法 */public sta ...