• [HDOJ4786]Fibonacci Tree 最小生成树


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4786

    先跑一遍最小生成树,注意判断是否已全部联通(用一个记号来统计最后生成树中有多少条边)。再记下最小生成树的权值和A。

    再反向排序,求一遍最大生成树。记下权值和B。问题转换成求[A,B]内是否有斐波那契数存在。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <iomanip>
      4 #include <cstring>
      5 #include <climits>
      6 #include <complex>
      7 #include <fstream>
      8 #include <cassert>
      9 #include <cstdio>
     10 #include <bitset>
     11 #include <vector>
     12 #include <deque>
     13 #include <queue>
     14 #include <stack>
     15 #include <ctime>
     16 #include <set>
     17 #include <map>
     18 #include <cmath>
     19 
     20 using namespace std;
     21 
     22 typedef struct P {
     23     int u;
     24     int v;
     25     int w;
     26 }P;
     27 
     28 bool cmp1(P p1, P p2) {return p1.w < p2.w;}
     29 bool cmp2(P p1, P p2) {return p1.w > p2.w;}
     30 int A, B;
     31 
     32 const int maxn = 100010;
     33 int n, m, cnt;
     34 int pre[maxn];
     35 int fib[maxn];
     36 P e[maxn];
     37 
     38 int find(int x) {
     39     return x == pre[x] ? pre[x] : pre[x] = find(pre[x]);
     40 }
     41 
     42 bool unite(int x, int y) {
     43     x = find(x);
     44     y = find(y);
     45     if(x != y) {
     46         pre[x] = y;
     47         return 1;
     48     }
     49     return 0;
     50 }
     51 
     52 void init() {
     53     for(int i = 0; i < maxn; i++) {
     54         pre[i] = i;
     55     }
     56 }
     57 
     58 void clear() {
     59     init();
     60     memset(e, 0, sizeof(e));
     61     A = 0, B = 0;
     62     cnt = 0;
     63 }
     64 
     65 int main() {
     66     // freopen("in", "r", stdin);
     67     int T;
     68     fib[0] = 0, fib[1] = 1, fib[2] = 1;
     69     for(int i = 3; i <= 26; i++) {
     70         fib[i] = fib[i-1] + fib[i-2];
     71     }
     72     scanf("%d", &T);
     73     for(int _ = 1; _ <= T; _++) {
     74         printf("Case #%d: ", _);
     75         clear();
     76         scanf("%d %d", &n, &m);
     77         for(int i = 0; i < m; i++) {
     78             scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
     79         }
     80         sort(e, e+m, cmp1);
     81         for(int i = 0; i < m; i++) {
     82             if(unite(e[i].u, e[i].v)) {
     83                 A += e[i].w;
     84                 cnt++;
     85             }
     86         }
     87         if(cnt != n - 1) printf("No
    ");
     88         else {
     89             init();
     90             sort(e, e+m, cmp2);
     91             for(int i = 0; i < m; i++) {
     92                 if(unite(e[i].u, e[i].v)) {
     93                     B += e[i].w;
     94                     cnt++;
     95                 }
     96             }
     97             int flag = 0;
     98             for(int i = 1; i <= 25; i++) {
     99                 if(fib[i] <= B && fib[i] >= A) {
    100                     flag = 1;
    101                     break;
    102                 }
    103             }
    104             if(flag) printf("Yes
    ");
    105             else printf("No
    ");
    106         }
    107     }
    108 }

    还排序个毛啊,直接反着跑一遍QAQ,反正有序的,二分查找一下不好吗。。。肥不拉几序列只要前25个,打一个小表就行了QAQ。。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <iomanip>
      4 #include <cstring>
      5 #include <climits>
      6 #include <complex>
      7 #include <fstream>
      8 #include <cassert>
      9 #include <cstdio>
     10 #include <bitset>
     11 #include <vector>
     12 #include <deque>
     13 #include <queue>
     14 #include <stack>
     15 #include <ctime>
     16 #include <set>
     17 #include <map>
     18 #include <cmath>
     19 
     20 using namespace std;
     21 
     22 typedef struct P {
     23     int u;
     24     int v;
     25     int w;
     26 }P;
     27 
     28 bool cmp1(P p1, P p2) {return p1.w < p2.w;}
     29 bool cmp2(P p1, P p2) {return p1.w > p2.w;}
     30 int A, B;
     31 
     32 const int maxn = 100010;
     33 int n, m, cnt;
     34 int pre[maxn];
     35 int fib[maxn];
     36 P e[maxn];
     37 
     38 int find(int x) {
     39     return x == pre[x] ? pre[x] : pre[x] = find(pre[x]);
     40 }
     41 
     42 bool unite(int x, int y) {
     43     x = find(x);
     44     y = find(y);
     45     if(x != y) {
     46         pre[x] = y;
     47         return 1;
     48     }
     49     return 0;
     50 }
     51 
     52 void init() {
     53     for(int i = 0; i < maxn; i++) {
     54         pre[i] = i;
     55     }
     56 }
     57 
     58 void clear() {
     59     init();
     60     memset(e, 0, sizeof(e));
     61     A = 0, B = 0;
     62     cnt = 0;
     63 }
     64 
     65 void __FIB__() {
     66     fib[0]=0,fib[1]=1,fib[2]=1,fib[3]=2,fib[4]=3,fib[5]=5,
     67     fib[6]=8,fib[7]=13,fib[8]=21,fib[9]=34,fib[10]=55,
     68     fib[11]=89,fib[12]=144,fib[13]=233,fib[14]=377,
     69     fib[15]=610,fib[16]=987,fib[17]=1597,fib[18]=2584,
     70     fib[19]=4181,fib[20]=6765,fib[21]=10946,fib[22]=17711,
     71     fib[23]=28657,fib[24]=46368,fib[25]=75025;
     72 }
     73 
     74 int main() {
     75     // freopen("in", "r", stdin);
     76     // freopen("out", "w", stdout);
     77     int T;
     78     __FIB__();
     79     scanf("%d", &T);
     80     for(int _ = 1; _ <= T; _++) {
     81         printf("Case #%d: ", _);
     82         clear();
     83         scanf("%d %d", &n, &m);
     84         for(int i = 0; i < m; i++) {
     85             scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
     86         }
     87         sort(e, e+m, cmp1);
     88         for(int i = 0; i < m; i++) {
     89             if(unite(e[i].u, e[i].v)) {
     90                 A += e[i].w;
     91                 cnt++;
     92             }
     93         }
     94         if(cnt != n - 1) printf("No
    ");
     95         else {
     96             init();
     97             for(int i = m; i >= 0; i--) {
     98                 if(unite(e[i].u, e[i].v)) {
     99                     B += e[i].w;
    100                     cnt++;
    101                 }
    102             }
    103             int flag = 0;
    104             int ll = 1, rr = 25;
    105             while(ll < rr) {
    106                 int mm = (ll + rr) >> 1;
    107                 if(fib[mm] <= B && fib[mm] >= A) {
    108                     flag = 1;
    109                     break;
    110                 }
    111                 else if(fib[mm] > B) rr = mm;
    112                 else if(fib[mm] < A) ll = mm + 1;
    113             }
    114             if(flag) printf("Yes
    ");
    115             else printf("No
    ");
    116         }
    117     }
    118 }
  • 相关阅读:
    批量执行工具PSSH详解
    详解IPTABLES
    nginx启动脚本
    ansible离线安装
    Linux性能评估工具
    Python中路径操作
    mongodb Enable Auth
    MySQL配置参数说明
    redis未授权访问
    php反序列化笔记
  • 原文地址:https://www.cnblogs.com/kirai/p/4948065.html
Copyright © 2020-2023  润新知