国庆万岁!!!!!

【题目大意】

给定一张无向图,有两种边的类型为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]免费道路的更多相关文章

  1. [BZOJ3624][Apio2008]免费道路

    [BZOJ3624][Apio2008]免费道路 试题描述 输入 输出 输入示例 输出示例 数据规模及约定 见“输入”. 题解 第一步,先尽量加入 c = 1 的边,若未形成一个连通块,则得到必须加入 ...

  2. BZOJ3624: [Apio2008]免费道路(最小生成树)

    题意 题目链接 Sol 首先答案一定是一棵树 这棵树上有一些0边是必须要选的,我们先把他们找出来,如果数量$\geqslant k$显然无解 再考虑继续往里面加0的边,判断能否加到k条即可 具体做法是 ...

  3. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  4. BZOJ 3624: [Apio2008]免费道路

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1201  Solved:  ...

  5. bzoj 3624: [Apio2008]免费道路 生成树的构造

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 111  Solved: 4 ...

  6. 题解 Luogu P3623 [APIO2008]免费道路

    [APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可 ...

  7. [Apio2008]免费道路[Kruscal]

    3624: [Apio2008]免费道路 Time Limit: 2 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1292  Solved:  ...

  8. P3623 [APIO2008]免费道路

    3624: [Apio2008]免费道路 Time Limit: 2 Sec Memory Limit: 128 MBSec Special Judge Submit: 2143 Solved: 88 ...

  9. [APIO2008]免费道路

    [APIO2008]免费道路 BZOJ luogu 先把必须连的鹅卵石路连上,大于k条no solution 什么样的鹅卵石路(u,v)必须连?所有水泥路都连上仍然不能使u,v连通的必须连 补全到k条 ...

随机推荐

  1. ajax做显示信息以后用ajax、Bootstrp做弹窗显示信息详情

    1.用ajax做弹窗显示信息详情 nation.php <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu ...

  2. nesC编程入门

    1.接口 NesC程序主要由各式组件(component)构成,组件和组件之间通过特定的接口(interface)互相沟通.一个接口内声明了提供相关服务的方法(C语言函数).例如数据读取接口(Read ...

  3. 用C#实现对MSSqlServer数据库的增删改查---Server层(WaterLevelSetServer.cs、DeviceSetServer.cs)

    在Server层定义WaterLevelSetServer和WaterLevelRecordServer两个子类,分别继承DeviceSetServer和DeviceRecordServer. usi ...

  4. 关于DataTable.Select不到数据的一种解决方案

    网上有很多说的,试过,都没用.自己研究了一下,解决方案如下: 建立dataview,用dv.rowfilter,就可以取到了,然后TOTABLE即可. 代码如下:(只看中间那几句即可) private ...

  5. GitBash、EGit、SourceTree三个Git管理工具对比

    Git管理工具对比(GitBash.EGit.SourceTree) GitBash是采用命令行的方式对版本进行管理,功能最为灵活强大,但是由于需要手动输入希望修改的文件名,所以相对繁琐. EGit是 ...

  6. linux中的vim 编辑一行内容,如何使光标快速移动到行首和行尾以及行中间某处啊?

    光标定位G 移至行行首nG 移至第n行行首n+ 移n行行首n- 移n行行首n$ 移n行(1表示本行)行尾0 所行行首$ 所行行尾^ 所行首字母h,j,k,l 左移移移右移H 前屏幕首行行首M 屏幕显示 ...

  7. 邀请用户进TestFlight 体验 App 的测试版本

    iphone手机用户,在工作中常见到,APP版本现在是Beta阶段(iOS版本),需要邀请一些用户来体验新版本,在版本上线前提出更好的建议及时进行修改,此时用到了testflight,很方便的通过邀请 ...

  8. ORA-12537: TNS:connection closed错误处理过程

    https://blog.csdn.net/mchdba/article/details/50018571

  9. python操作json数据格式--基础

    非常基础的json库的用法,后续添加数据格式.编码等内容 参考文章 json进阶 Python的json模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps ...

  10. 在LoadRunner中从数组类型的参数随机取值的方法

    在LoadRunner中从数组类型的参数随机取值的方法 使用web_reg_save_param做关联后,有时候会有多个匹配值. 为了模仿用户行为随机取一个值为后续transcation所用,可以使用 ...