日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fibonacci Tree HDU - 4786——解题报告

發布時間:2024/2/28 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fibonacci Tree HDU - 4786——解题报告 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

立志用更少的代碼做更高效的表達


  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


分析

題意:一個圖,有黑邊和白邊,黑邊權值0,白邊權值1, 問是否存在一棵生成樹,使其白邊個數(也就是總權值)為斐波那契數(1,2,3,5…)。

生成樹的概念: n個點,n-1條邊,沒有環路。

思路: 構造一個最大生成樹, 構造一個最小生成樹, 只要二者權值之間存在斐波那契數,則Yes, 因為權值每-1,一定是將一個黑邊換成了白邊。


代碼展示

/* 步驟: 1、定義結構體, 定義重載運算符 2、初始化并查集(init函數) 3、定義find函數 4、定義連接邊的函數(max函數) 5、定義建立樹的函數 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1e5 + 5;struct node{int u, v, w; //u、v是點,w是它本身的值 node() { }node(int uu, int vv, int ww) {u = uu; v = vv; w = ww;}bool operator<(const node other)const { //重載操作數 return w<other.w;} }edge[N*2];int n, m; int per[N]; int fib[N]; //斐波那契數列 void init() { //1、創建初始化的并查集 for(int i = 0; i < N; i++) per[i]=i; } int Find(int x) { //2、找邊的函數 return per[x] == x ? x : per[x]=Find(per[x]); }int mix(int a, int b) { //建立連接的過程 int fa = Find(a), fb = Find(b);if(fa != fb) {per[fa] = fb;return 1;} return 0; } int solve1() {init(); //先初始化int ans = 0, cnt = 0;for(int i = 0; i < m; i++) {int u = edge[i].u;int v = edge[i].v;int w = edge[i].w;if(mix(u,v)) {cnt++; ans+=w; //若建立連接成功,cnt邊數增加, 權值增加 }if(cnt == n-1) break; //如果邊數=n-1,則結束遍歷 } if(cnt == n-1) return ans; //如果建樹成功,則返回權值else return 0; //否則返回0 }int solve2() {init();int ans = 0, cnt = 0;for(int i = m-1; i >= 0; i--) {int u = edge[i].u;int v = edge[i].v;int w = edge[i].w;if(mix(u,v)) {cnt++;ans += w;}if(cnt == n-1) break;}if(cnt == n-1) return ans;return 0; }void in() { //構造斐波那契數列, 打表 memset(fib, 0, sizeof(fib));int a = 1, b = 1; fib[1] = 1;for(int i = 2; i <= 30; i++) {int c = a+b;if(c>=N) break;a = b; b = c; fib[c] = 1;} }int main() {int T, cas=0;scanf("%d", &T);in(); while(T--) {scanf("%d%d", &n, &m);for(int i = 0; i < m; i++) {int u, v, w;scanf("%d%d%d", &u, &v, &w);edge[i] = node(u, v, w);}//按權值排序, 正向遍歷則最小生成樹,反向遍歷則最大生成樹 sort(edge, edge+m); int mint = solve1();int maxt = solve2();int flag = 0; for(int i = mint; i <= maxt; i++) if(fib[i]) { flag = 1; break; }printf("Case #%d: ", ++cas);if(flag) printf("Yes\n");else printf("No\n");} return 0; }

每日一句

懦弱囚禁人的靈魂,希望可以令你感受自由, 強者自救,圣者渡人。——《肖申克的救贖》

總結

以上是生活随笔為你收集整理的Fibonacci Tree HDU - 4786——解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。