免费道路

Time Limit: 2 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  

Input

  

Output

  

Sample Input

  5 7 2
  1 3 0
  4 5 1
  3 2 0
  5 3 1
  4 3 0
  1 2 1
  4 2 1

Sample Output

  3 2 0
  4 3 0
  5 3 1
  1 2 1

HINT

  1<=n<=20000,1<=m<=100000,0<=k<=n-1

Main idea

  一种0边,一种1边,求一棵最小生成树并且正好有K条0边,输出其中一种方案。

Solution

  显然要搞一棵符合题目的生成树。

  每次要加入0边或者1边,直接做肯定不可行,考虑有什么0边是一定要加入的。

  只需要输出一种方案,所以我们先加入所有可加的1边,如果图不联通则加入可加入的0边,那么这几条0边在我们所求的方案中是一定需要加入的。

  这时候判断一下,如果此时加入的0边数量>K,或者图还是无法联通的话则无解。然后处理完毕前半部分,考虑接下来如何实现。

  因为我们要使得图为树并且正好有K条0边,运用贪心,想到了加入0边到K条位置(如果到不了K条则也无解),然后剩下的用1边来填。

  验证一下这样做的可行性:由于我们在前半部分使得了可以成为一棵树,那么显然我们在后半部分中每加入一条0边,则在前半部分中一定有一条1边可以替换使得可行(因为前半部分是尽量加入1边)。每次连边判环运用Krusal即可。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE=;
const int INF=; int n,m,k;
int Edge_k;
int fa[ONE];
int num;
int Choose[ONE];
int ans_num;
int the0; struct power
{
int x,y,v;
}a[ONE],Ans_edg[ONE]; int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int find(int x)
{
if(fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
} void Un(int a,int b)
{
int a1=find(a);
int b1=find(b);
if(a1!=b1) fa[a1]=b1;
} int Add_set(int N,int v,int ci)
{
int kd=;
for(int i=;i<=m;i++)
{
if(kd>=N) break; if(a[i].v!=v) continue; int x=a[i].x,y=a[i].y;
if(find(x)!=find(y))
{
Un(x,y);
if(ci>=) Ans_edg[++ans_num]=a[i];
if(ci==)
{
Choose[++num]=i;
}
Edge_k++;
kd++;
if(ci==) the0++;
}
if(Edge_k==n-) break;
}
} int main()
{
n=get(); m=get(); k=get();
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=m;i++)
{
a[i].x=get(); a[i].y=get(); a[i].v=get();
}
Edge_k=; Add_set(INF,,);
Add_set(INF,,); if(Edge_k<n- || num>k)
{
printf("no solution\n");
return ;
} Edge_k=;
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=num;i++)
{
int x=Choose[i];
Un(a[x].x,a[x].y);
Edge_k++;
if(Edge_k==n-) break;
} Add_set(k-num,,);
if(the0!=k-num)
{
printf("no solution\n");
return ;
} Add_set(INF,,);
for(int i=;i<=ans_num;i++)
{
printf("%d %d %d\n",Ans_edg[i].x,Ans_edg[i].y,Ans_edg[i].v);
} }

【BZOJ3624】【APIO2008】免费道路 [生成树][贪心]的更多相关文章

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

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

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

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

  3. [APIO2008]免费道路(生成树)

    新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可能保持所有道路免费.为此亟待制定一个新的 ...

  4. Bzoj 3624: [Apio2008]免费道路 (贪心+生成树)

    Sample Input 5 7 2 1 3 0 4 5 1 3 2 0 5 3 1 4 3 0 1 2 1 4 2 1 Sample Output 3 2 0 4 3 0 5 3 1 1 2 1 这 ...

  5. BZOJ 3624: [Apio2008]免费道路 [生成树 并查集]

    题意: 一张图0,1两种边,构造一个恰有k条0边的生成树 优先选择1边构造生成树,看看0边是否小于k 然后保留这些0边,补齐k条,再加1边一定能构成生成树 类似kruskal的证明 #include ...

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

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

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

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

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

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

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

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

随机推荐

  1. spring、spring-data-redis整合使用

    一.Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 从2010年3月15日起,Redis的开发工作由VMwa ...

  2. php-configure错误解决

    configure: error: libjpeg.(a|so) not foundconfigure: error: libjpeg.(a|so) not foundln -sf libjpeg.s ...

  3. APPium-python实例(记录)

    https://github.com/appium/sample-code/tree/master/sample-code/examples/python

  4. Python 3基础教程23-多维列表

    这里简单举例一个多维列表,多维看起来都很晕. # 多维列表 x = [ [5,6],[6,7],[7,2] ,[2,5] ,[4,9]] print(x) # 根据索引引用列表元素,例如打印[6,7] ...

  5. 阿里的100TB Sort Benchmark排序比雅虎快了一倍还多,我的看法

    如果我的判断正确,它们使用的软件和算法应该是HADOOP,MAP/REDUCE,或者类似的技术方案.如果这些条件一样,影响计算结果的还有三个因素: 1.CPU的数量和CPU的处理能力     CPU的 ...

  6. kafka常用命令笔记

    0.查看有哪些主题: ./kafka-topics.sh --list --zookeeper 192.168.0.201:12181 1.查看topic的详细信息 ./kafka-topics.sh ...

  7. 修复 Ubuntu 中“Unable to lock the administration directory (/var/lib/dpkg/)”

    在 Ubuntu 或者它的衍生版如 Linux Mint(我已经作为日常工作使用的系统)中使用 apt-get 命令或者其相对更新的APT 管理工具时,你可能会在命令行中看到一个 unable to ...

  8. hbase1.2.6完全分布式安装

    环境,参考之前的两篇博文: jdk1.7 hadoop2.6.0 完全分布式 一个master,slave1,slave2,slave3 zookeeper3.4.6 完全分布式 安装与配置:(以下步 ...

  9. java课程设计 学生管理系统

    学生成绩管理系统 可实现功能 学生管理系统 查询学生信息:姓名.学号.性别.出生年月日.(学号自动生成且唯一) 查询学生成绩:每个人都有数学.Java与体育与选修课 查询学生课程 进行公选课选课 教师 ...

  10. lintcode-115-不同的路径 II

    115-不同的路径 II "不同的路径" 的跟进问题: 现在考虑网格中有障碍物,那样将会有多少条不同的路径? 网格中的障碍和空位置分别用 1 和 0 来表示. 注意事项 m 和 n ...