题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3624

题意:

  给你一个无向图,n个点,m条边。

  有两种边,种类分别用0和1表示。

  让你求一棵生成树,使得这棵树中恰好有k条0种类的边。输出每一条边的两端点和种类。

  若无解,则输出"no solution"。

题解:

  让0和1分别作两种边的边权。

  步骤:

    (1)先找出必须选的0边。(优先选1,最大生成树)

    (2)再将0边个数加至k。

    (3)补上1边。

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAX_N 20005 using namespace std; struct Edge
{
int sour;
int dest;
int len;
Edge(int _sour,int _dest,int _len)
{
sour=_sour;
dest=_dest;
len=_len;
}
Edge(){}
friend bool operator < (const Edge &a,const Edge &b)
{
return a.len<b.len;
}
}; int n,m,k;
int par[MAX_N];
bool failed=false;
vector<Edge> edge;
vector<Edge> est;
vector<Edge> ans; void read()
{
cin>>n>>m>>k;
int a,b,c;
for(int i=;i<m;i++)
{
cin>>a>>b>>c;
edge.push_back(Edge(a,b,c));
}
} void init_union_find()
{
for(int i=;i<=n;i++)
{
par[i]=i;
}
} int find(int x)
{
return par[x]==x?x:par[x]=find(par[x]);
} void unite(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py) return;
par[px]=py;
} bool same(int x,int y)
{
return find(x)==find(y);
} void max_tree()
{
init_union_find();
sort(edge.begin(),edge.end());
int cnt=;
for(int i=edge.size()-;i>=;i--)
{
Edge temp=edge[i];
if(!same(temp.sour,temp.dest))
{
cnt++;
unite(temp.sour,temp.dest);
if(temp.len==) est.push_back(temp);
}
}
if(cnt!=n- || est.size()>k) failed=true;
} void min_tree()
{
init_union_find();
int cnt=;
int spe=;
for(int i=;i<est.size() && spe<k;i++)
{
Edge temp=est[i];
cnt++;
spe++;
ans.push_back(temp);
unite(temp.sour,temp.dest);
}
for(int i=;i<edge.size();i++)
{
Edge temp=edge[i];
if(!same(temp.sour,temp.dest))
{
if(temp.len==)
{
if(spe<k)
{
cnt++;
spe++;
ans.push_back(temp);
unite(temp.sour,temp.dest);
}
}
else
{
cnt++;
ans.push_back(temp);
unite(temp.sour,temp.dest);
}
}
}
if(cnt!=n- || spe!=k) failed=true;
} void solve()
{
max_tree();
min_tree();
} void print()
{
if(failed)
{
cout<<"no solution"<<endl;
return;
}
for(int i=;i<ans.size();i++)
{
Edge temp=ans[i];
cout<<temp.sour<<" "<<temp.dest<<" "<<temp.len<<endl;
}
} int main()
{
read();
solve();
print();
}

BZOJ 3624 [Apio2008]免费道路:并查集 + 生成树 + 贪心【恰有k条特殊路径】的更多相关文章

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

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

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

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

  3. bzoj 3624: [Apio2008]免费道路【生成树+贪心】

    先把水泥路建生成树,然后加鹅卵石路,这里加的鹅卵石路是一定要用的(连接各个联通块),然后初始化并查集,先把必需的鹅卵石路加进去,然后随便加鹅卵石路直到k条,然后加水泥路即可. 注意判断无解 #incl ...

  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. BZOJ.3624.[APIO2008]免费道路(Kruskal)

    题目链接 我们发现有些白边是必须加的,有些是多余的. 那么我们先把所有黑边加进去,然后把必须要加的白边找出来. 然后Kruskal,把必须要加的白边先加进去,小于K的话再加能加的白边.然后加黑边. 要 ...

  7. 3624: [Apio2008]免费道路

    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 ...

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

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

  9. P3623 [APIO2008]免费道路

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

随机推荐

  1. 怎样在编译的时候,控制删除apk不用的资源?

    1.改动alps/meidatek/config/xxx/ProjectConfig.mk下的MTK_PRODUCT_LOCALS,去掉不用的资源,比方屏幕密度或语言等.  2. nodpi和mipm ...

  2. php迭代器模式

    其实就是遍历数组 然后对数组中的元素进行操作 实现iterator接口即可.

  3. Web大文件(夹)上传(断点续传)控件-Xproer.HttpUploader6

    版权所有 2009-2017荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/up6.2/in ...

  4. JVM完全指南

    JVM完全指南     一:虚拟机内存图解   JAVA程序运行与虚拟机之上,运行时需要内存空间.虚拟机执行JAVA程序的过程中会把它管理的内存划分为不同的数据区域方便管理.     虚拟机管理内存数 ...

  5. 不同特权级间代码段的跳转{ 门 + 跳转(jmp + call) + 返回(ret) }

    [0]写在前面 0.1)我们讲 CPU的保护机制,它是可靠的多任务运行环境所必须的: 0.2) CPU保护机制:分为段级保护 + 页级保护: 0.2.1)段级保护分为:段限长 limit 检查.段类型 ...

  6. ssh无密码登陆权威指南

    [0]写在前面 由于ssh 实现的是免密码登陆,大致步骤是: 0.1) client通过ssh登陆到server: 0.2) server检查家目录下的.ssh文件, 并发送公钥文件 authoriz ...

  7. python发布IIS

    参考文档 https://segmentfault.com/a/1190000008909201 http://blog.51cto.com/anngle/1922041 https://www.cn ...

  8. c#数组的count()和length的区别

    C# 数组中 Length 表示数组项的个数,是个属性. 而 Count() 也是表示项的个数,是个方法,它的值和 Length 一样.但实际上严格地说 Count() 不是数组的内容,而是 IEnu ...

  9. 小程序的生命周期 launchApp

    https://developers.weixin.qq.com/miniprogram/dev/api/launchApp.html?search-key=生命周期 launchApp(OBJECT ...

  10. svn服务的安装和使用

    更新linux软件库 cat /etc/redhat-release wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.c ...