上题:
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, ... )
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 <= 10 5) and M(0 <= M <= 10 5).
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).
For each test case, the first line contains two integers N(1 <= N <= 10 5) and M(0 <= M <= 10 5).
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题意:题的意思是给你一个无向图,有n个节点和m条边,你可以对这几个顶点进行染色,其实1表示的是白色,0表示的黑色,让你从这个图中找到边权和为斐波那契数的一棵树。起初题意看的不是特别懂,正好队友一直在写b题,我就安心看,大概意思貌似是这个意思,结果他们b题一直在debug。。后来发现是题意理解错了,,简直傻逼,,我上手敲这道题的时候只剩下不到40分钟了,最后 没a出来,,,还是太菜了,,下面说一下 怎样写这道题,之后再讲为什么,我们先求出生成树中 ,边权最小和边权最大的值(也就是说 生成树中最少需要的白边数量和最多需要的白边数量),之后只要这中间有斐波那契数,你就是符合要求的,现在说为什么,首先我们得到的最小生成树的值,表示的是 生成这颗树,最少需要的白边数量,对吧,而最大生成树,是最多需要的白边数量,所以在这个区间内,我们总能找到一条白边去替换一条黑边或者一条黑边去替换一条白边,这样他得到的还是一棵生成树。然后说一下我无限错误的地方吧,首先是我的sort函数,排序的时候应该是从1->m,而我写成了从1->n,worng n多发,。,之后就是打表斐波那契。。。写错了。。都是些不应该错的小细节,结果自己 一直发现不了。。太菜了上代码#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxn=100002; int n,m; struct node { int x,y; int value; }edg[maxn]; int p[maxn]; int a[100000]; bool cmp(node a,node b) { return a.value<b.value; } int getf(int x) { return x==p[x]?x:p[x]=getf(p[x]); } void init() { memset(a,0,sizeof(a)); int r=a[1]=1; int l=a[2]=2; for(int i=3;i<=25;i++) { a[r+l]=1; // printf("%d \n",r+l); int t=l; l=r+l; r=t; if(r+l>=10002) { break; } } } int k1(int n,int m) { int sum=0,ans=0; for(int i=0;i<=n;i++) { p[i]=i; } for(int i=1;i<=m;i++) { int x=edg[i].x; int y=edg[i].y; int dx=getf(x); int dy=getf(y); if(dx!=dy) { p[dy]=dx; ans+=edg[i].value; sum++; } if(sum==n-1) { break; } } if(sum<n-1) { return -1; } return ans; } int k2(int n,int m) { int sum=0,ans=0; for(int i=0;i<=n;i++) { p[i]=i; } for(int i=m;i>=1;i--) { int x=edg[i].x; int y=edg[i].y; int dx=getf(x); int dy=getf(y); if(dx!=dy) { p[dy]=dx; ans+=edg[i].value; sum++; } if(sum==n-1) { break; } } if(sum<n-1) { return -1; } return ans; } int main() { init(); int t; int ca=1; scanf("%d",&t); init(); while(t--) { memset(edg,0,sizeof(edg)); memset(p,0,sizeof(p)); int flag=0; scanf("%d%d",&n,&m); if(n==0) { printf("Case #%d: No\n",ca++); continue; } for(int i=1;i<=m;i++) { scanf("%d%d%d",&edg[i].x,&edg[i].y,&edg[i].value); } sort(edg+1,edg+1+m,cmp); int l=k1(n,m);//最小生成树 int r=k2(n,m);//最大生成树 // printf("l=%d r=%d\n",l,r); if(l==-1||r==-1) { printf("Case #%d: No\n",ca++); continue; } for(int i=l;i<=r;i++) { if(a[i]) { flag=1; break; } } if(flag) { printf("Case #%d: Yes\n",ca++); } else { printf("Case #%d: No\n",ca++); } } } /*10000 5 14 1 2 0 1 3 0 1 4 0 1 5 0 2 1 1 2 3 1 2 4 1 1 4 0 2 3 1 3 4 1 4 5 1 2 4 1 3 5 0 4 2 0 3 4 1 2 1 1 3 0 2 3 1 2 3 0 11 5 1 10 0 1 9 2 1 8 1 1 4 1 2 3 0 */