CODEFORCES 125E MST Company 巧用Kruskal算法
题意:给定一个带权边无向图,求最小生成树,且满足第一个节点的度为固定的k 无解则输出-1
数据规模: 节点数n和限制k<=5000 边数m<=10^5 时限8sec
思路:
首先时限比较宽,第一个想到的暴力做法是枚举第一个节点(即首都)选中的K条边,复杂度为阶乘级别 无法接受。但是我们可以确定,问题的关键在于在所有国道中选择哪k条国道。一旦k条国道选定,最小生成树就是固定的。
考虑一个极端的情况,如果我们直接对这个图运行Kruskal算法,得到了一个树 且 第一个节点的度为k,则这就是正确的答案。当然,一般数据是无法做到的。
那么我们就可以使用一个技巧,如果运行Kruskal算法后第一个节点的度小于k,那么我们在算法运行的序列中将所有国道的位置整体向前移动,使得下一次运行Kruskal算法可以选定更多的国道,我们就离正确答案更近了。反之亦然。
那么怎样调整所有“国道”在Kruskal序列中的位置呢?
选定一个double值mid 它可以很大,也可以很小,在排序时“国道”的权值加上这个mid再与非国道比较,就可以适当的调节所有“国道”在序列中的位置。
代码如下,只要理解了排序比较函数cmp 也就理解了这个Kruskal的变种算法了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=+,maxm=+;
int x[maxm],y[maxm],w[maxm],sig[maxm],ance[maxn],ans[maxn];
int n,m,k,tot,cnt,captedge;
double l,r,mid;
bool cmp(int a,int b)
{
return (w[a]+(x[a]==)*mid)<(w[b]+(x[b]==)*mid);//这个算法的核心
}
int findance(int x)
{
if(x==ance[x])return x;
else return ance[x]=findance(ance[x]);
}
void Kruskal(bool flag)
{
cnt=captedge=;
for(int i=;i<=n;i++)
{
ance[i]=i;
}
sort(sig,sig+m,cmp);
for(int i=;i<m;i++)
{
if(cnt+==n) return ;
int j=sig[i];
int u=findance(x[j]),v=findance(y[j]);
if((u!=v)&&(flag||(captedge+(x[j]==))<=k)) {
ance[u]=v;
ans[cnt++]=j;
if(x[j]==)captedge++;
}
}
}
int main()
{
ios::sync_with_stdio(false);
freopen("t.txt","r",stdin);
cin>>n>>m>>k;
tot=;
for(int i=;i<m;i++)
{
sig[i]=i;
cin>>x[i]>>y[i]>>w[i];
if(x[i]>y[i]){int t=x[i];x[i]=y[i];y[i]=t;}//swap
if(x[i]==)tot++;
}
if((k>tot)||(k==&&n>))
{
cout<<"-1"<<endl;
return ;
}
cnt=;
Kruskal();
if(cnt!=(n-))
{
cout<<"-1"<<endl;
return ;
}
l=(-)*100000.0;
r=100000.0;
while(((l+1e-)<r)&&(captedge!=k))
{
mid=(l+r)/2.0;
Kruskal();
if(captedge<k)r=mid;
else l=mid;
}
if(captedge!=k)mid=(l+r)/2.0;
Kruskal();
cout<<n-<<endl;
if(cnt>=)cout<<ans[]+;
for(int i=;i<cnt;i++)
cout<<" "<<ans[i]+;
cout<<endl;
return ;
}
CODEFORCES 125E MST Company 巧用Kruskal算法的更多相关文章
- CodeForces 125E MST Company
E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...
- POJ 1679 The Unique MST (次小生成树kruskal算法)
The Unique MST 时间限制: 10 Sec 内存限制: 128 MB提交: 25 解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...
- MST最小生成树及克鲁斯卡尔(Kruskal)算法
最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...
- HDU 2682 Tree(Kruskal算法求解MST)
题目: There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and ...
- HDU 5253 连接的管道(Kruskal算法求解MST)
题目: 老 Jack 有一片农田,以往几年都是靠天吃饭的.但是今年老天格外的不开眼,大旱.所以老 Jack 决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行灌溉了.当老 J ...
- ZOJ 1586 QS Network(Kruskal算法求解MST)
题目: In the planet w-503 of galaxy cgb, there is a kind of intelligent creature named QS. QScommunica ...
- POJ 1251 Jungle Roads(Kruskal算法求解MST)
题目: The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money w ...
- 最小生成树(MST)Prim算法和Kruskal算法
刚学完最小生成树,赶紧写写学习的心得(其实是怕我自己忘了) 最小生成树概念:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 就是说 ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
随机推荐
- PAT (Advanced Level) 1028. List Sorting (25)
时间卡的比较死,用string会超时. #include<cstdio> #include<cstring> #include<cmath> #include< ...
- BNU OJ 50998 BQG's Messy Code
#include <cstdio> #define _(l) int l #define ___(l,L) for (_(o)=0,x=l o*2;o<x;o++)O= L o; # ...
- SQL面试题——查询课程
题目: 成绩表(Grade),包含字段:GradeID(Int,自增), SNO(int, 学号), CNO(int, 课程号), Score(float,分数) 查询每门课程的平均(最高/最低)分及 ...
- The 2014 ACMICPC Asia Regional Guangzhou Online
[A]-_-/// [B]线段树+位运算(感觉可出) [C]地图BFS,找最长线 [D]地图BFS,加上各种复杂情况的最短路-_- [E]-_-/// [F]三分+圆与线段的交点,计算几何 [G]-_ ...
- javascript 中 arguments.callee属性
javascript 中 arguments.callee属性 可以在函数内部,指向的是这个函数(或者叫做“类”)本身. 相当于PHP 中的 self 关键字. The arguments.calle ...
- Linux程序设计中的curses.h编译报错,无法找到curses.h和ncurses.h
源程序screen.c如下: #include <stdio.h> #include <term.h> #include <curses.h> #include & ...
- Sematic库系列一
最近在做项目时采用了sematic css 库,由于这个库的资料太少,在做项目中遇到很多问题,在这里做一些记录 1. 下拉框demo HTML 代码 <div class="field ...
- P3197 [HNOI2008]越狱
题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 输入输出格式 输入 ...
- iOS开发——WAVE音频文件解析
WAV文件也分了好几类,相应的非数据信息存储在文件的头部,下面简单的提一下,然后在最后重点介绍44字节的那种,一般用的都是这个. 1.8KHz采样.16比特量化的线性PCM语音信号的WAVE文件头格式 ...
- ubuntu16安装KVM
apt install qemu-kvm libvirt-bin apt install openvswitch-switch