给n个点,m条边的图,每条边要么属于a公司,要么属于b公司。要求一颗最小生成树,条件是其中属于a公司的边数为k。
这题做法很巧妙。
要求最小生成树,但有一定限制,搜索、贪心显然都不对。
要是能找到一种合理的控制方法,使得求MST的过程中可以控制a公司边的数量,那样问题就解决了。
所以我们可以人为给a公司的边加上一定的权值,使得其中一些边不得不退出MST的选择范围内。
如果此时求的mst里a公司的边数>k,那么就要增加权值;边数<k时,权值为负。
所以,通过二分边权值,可以使得求得mst里所含a公司的边数逐渐逼近k,此时记录答案,因为一定有解,所以最终一定是所求答案。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxm=100010;
const int maxn=50010;
struct node
{
int u,v,w,ty;
}e[maxm];
int r[maxn],n,m,k,ret,telecom;
bool cmpw(node a,node b)
{
if(a.w!=b.w) return a.w<b.w;
return a.ty<b.ty;
}
int root(int a)
{
if(r[a]==-1) return a;
return r[a]=root(r[a]);
}
bool kru(int x)
{
for