题目链接: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. AutoCAD参照编辑期间不允许使用 SAVE 命令怎么办

    如下所示,点击保存按钮的时候下方出现如下提示:参照编辑期间不允许使用 SAVE 命令,同时图变成灰褐色,也无法改变颜色   点击修改-外部参照和块编辑-保存参照编辑即可.可以发现图的颜色也变正常了. ...

  2. C#托付之愚见

    C#托付起源 近期參加实习和奔走于各大招聘会,被问及非常多技术方面的问题.C#问的较多的就是托付和linq. linq之前已经写过一篇文章,能够參见 http://blog.csdn.net/yzys ...

  3. php创建无限极目录代码

    php创建无限极目录代码 <?php //无限级目录 function dirs($path,$mode=0777){ if(is_dir($path)){ echo '目录已经存在!'; }e ...

  4. Android利用reative_layout生成梅花界面

    XML代码: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:and ...

  5. 【GoldenGate】使用OGG,两个Oracle库之间单向同步数据

    ************************************************************************ ****原文:blog.csdn.net/clark_ ...

  6. 迁移,移动.vagrant.d目录

    默认在 C:\Users\***\.vagrant.d 然后下面有boxes目录 想迁移到其它目录 setx VAGRANT_HOME "/d/.vagrant.d/" setx ...

  7. FAT12中,如何定位大于一个扇区(512B)的文件内容

    [0]README 0.1)本文旨在于 演示在FAT12中, 如何取定位大于 512B 的文件内容,和查看它: 0.2)如何制作FAT12文件系统,以及如何向文件中添加temp.txt文件,参见: { ...

  8. 公网yum 源地址

    1. centos5.*  公网yum 源地址 [root@web ~]# cd /etc/yum.repos.d/[root@web yum.repos.d]# wget -O /etc/yum.r ...

  9. 九度OJ 1024:畅通工程 (最小生成树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3979 解决:1354 题目描述:     省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有 ...

  10. 【题解】Making The Grade(DP+结论)

    [题解]Making The Grade(DP+结论) VJ:Making the Grade HNOI-D2-T3 原题,禁赛三年. 或许是我做过的最简单的DP题了吧(一遍过是什么东西) 之前做过关 ...