http://acm.hdu.edu.cn/showproblem.php?pid=4263
给出n个点m个边
边的颜色有红和蓝
求是否存在恰好有k条蓝边的生成树
求一遍含蓝边最多的最小生成树
再求一次含蓝边最少的生成树(即红边最多)
若k在两者之间,则存在,否则不存在
构造的过程就是从 最少蓝边的图开始,加入一条蓝边,形成环,然后去掉一条红边,以此类推。。必能达到k蓝的情况
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int fa[1005];
int find(int x)
{
if (fa[x]==x)
return x;
else return fa[x]=find(fa[x]);
}
struct node
{
char cc;
int x,y;
node() {}
};
bool cmp(node a,node b)
{
return a.cc<b.cc;
}
node tm[1000005];
int main()
{
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if (!n&&!m&&!k)break;
char cc;
int x,y;
getchar();
for (int i=1; i<=m; i++)
{
scanf("%c %d %d",&tm[i].cc,&tm[i].x,&tm[i].y);
getchar();
}
sort(tm+1,tm+1+m,cmp);
for (int i=1; i<=n; i++) fa[i]=i;
int ans1=0;
for (int i=1; i<=m; i++)
{
int x=tm[i].x;
int y=tm[i].y;
int fx=find(x);
int fy=find(y);
if (fx!=fy)
{
fa[fx]=fy;
if (tm[i].cc=='B') ans1++;
}
}
int ans2=0;
for (int i=1; i<=n; i++) fa[i]=i;
for (int i=m; i>=1; i--)
{
int x=tm[i].x;
int y=tm[i].y;
int fx=find(x);
int fy=find(y);
if (fx!=fy)
{
fa[fx]=fy;
if (tm[i].cc=='R') ans2++;
}
}
ans2=n-1-ans2;
if (k>=ans2 && k<=ans1)
printf("1\n");
else
printf("0\n");
}
return 0;
}