Problem Description
Coach Pang is interested in Fibonacci numbers while Uncle Yang wants him to do some research on Spanning Tree. So Coach Pang decides to solve the following problem:
Consider a bidirectional graph G with N vertices and M edges. All edges are painted into either white or black. Can we find a Spanning Tree with some positive Fibonacci number of white edges?
(Fibonacci number is defined as 1, 2, 3, 5, 8, ... )
Input
The first line of the input contains an integer T, the number of test cases.
For each test case, the first line contains two integers N(1 <= N <= 105) and M(0 <= M <= 105).
Then M lines follow, each contains three integers u, v (1 <= u,v <= N, u<> v) and c (0 <= c <= 1), indicating an edge between u and v with a color c (1 for white and 0 for black).
Output
For each test case, output a line “Case #x: s”. x is the case number and s is either “Yes” or “No” (without quotes) representing the answer to the problem.
Sample Input
2
4 4
1 2 1
2 3 1
3 4 1
1 4 0
5 6
1 2 1
1 3 1
1 4 1
1 5 1
3 5 1
4 2 1
Sample Output
Case #1: Yes
Case #2: No
题意
给你一个图 有黑边白边 问最其生成树 中白边的数量是否可以组成最小生成树
分析
黑白两个很容易想到01而题目中也说了0和1。所以我们只需要求出生成树中最小的白边数和生成书中最大的白边数即可,此时,因为白边代表1那么我们只需要跑两边计算权值即可。
要注意图不联通的情况
这个代码写的真的丑
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int pre[maxn];
int tb[maxn];
set<int>st;
int n,m;
int cnt=0;
struct Road
{
int st,ed,w;
} rr[maxn];
bool cmp1 (Road a,Road b)
{
return a.w<b.w;
}
bool cmp2(Road a,Road b)
{
return a.w>b.w;
}
void init()
{
for(int i=1; i<=n; i++)
pre[i]=i;
cnt=0;
}
void table()
{
tb[0]=1;
tb[1]=1;
for(int i=2; i<25; i++)
tb[i]=tb[i-1]+tb[i-2];
for(int i=1; i<25; i++)
st.insert(tb[i]);
}
int find( int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x;
int j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
bool mer(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
{
pre[fa]=fb;
return true;
}
return false;
}
int scs()
{
int ans=0;
for(int i=1; i<=m; i++)
if(mer(rr[i].st,rr[i].ed))
ans+=rr[i].w;
cnt++;
return ans;
}
int main()
{
int T;
cin>>T;
table();
int tot=1;
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
scanf("%d%d%d",&rr[i].st,&rr[i].ed,&rr[i].w);
init();
sort(rr+1,rr+m+1,cmp1);
int cmin=scs();
init();
sort(rr+1,rr+m+1,cmp2);
int cmax=scs();
bool flag1=true;
for(int i=1; i<=n; i++)
{
if(find(i)!=find(1))
{
flag1=false;
break;
}
}
if(!flag1)
{
printf("Case #%d: No
",tot++);
continue;
}
bool flag2=false;
for(int i=cmin; i<=cmax; i++)
if(st.count(i)) flag2=1;
if(flag2)
printf("Case #%d: Yes
",tot++);
else
printf("Case #%d: No
",tot++);
}
return 0;
}