hdu4786 Fibonacci Tree(2013 成都 ),确定上下界,生成树

来源:互联网 发布:安卓开发 大数据存综 编辑:程序博客网 时间:2024/04/29 02:18

思维题

确定上下界,1边最少l个,最多r个,根据树的构造过程,必定可以用1边替换0边从而可到达1边l到r的个数

参考:http://blog.csdn.net/kk303/article/details/16368165

//#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FD(i, b, a) for(int i = (b); i >= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(a, v) memset(a, v, sizeof(a))#define PB push_back#define MP make_pairtypedef long long LL;const int INF = 0x3f3f3f3f;const int MAXN = 100010;int n, m;struct Edge{    int from, to, l;    Edge(){}    Edge(int from, int to, int l) : from(from), to(to), l(l) {}    bool operator<(const Edge& rhs) const    {        return l < rhs.l;///升序    }}E[MAXN];int fa[MAXN];void init_fa(int n){    for (int i = 0; i <= n; i++) fa[i] = i;}int findset(int x){ return x == fa[x] ? x : fa[x] = findset(fa[x]); }int solve(int op){    int l, addi;    if (op) l = m - 1, addi = -1;    else l = 0, addi = 1;    init_fa(n);    int ans = 0;    int cnt = 0;    for (int i = l; i <= m - 1 && i >= 0; i += addi)    {        int x = E[i].from, y = E[i].to, l = E[i].l;        int fax = findset(x), fay = findset(y);        if (fax != fay)        {            fa[fax] = fay;            ans += E[i].l;            cnt++;            if (cnt >= n - 1) break;        }    }    if (cnt < n - 1) return -1;    else return ans;}int fb[MAXN];int fb_cnt;void pre(){    fb[0] = 1, fb[1] = 2;    int i;    for (i = 2; ;i++)    {        fb[i] = fb[i - 1] + fb[i - 2];        if (fb[i] >= 100000) break;    }    fb_cnt = i;}int main (){    int nc = 1;    int T;    pre();    scanf("%d", &T);    while (T--)    {        scanf("%d%d",&n, &m);        REP(i, m)        {            scanf("%d%d%d", &E[i].from, &E[i].to, &E[i].l);        }        printf("Case #%d: ", nc++);        sort(E, E + m);        int lm , rm;        lm = solve(0);        if (lm < 0)        {            printf("No\n");            continue;        }        rm = solve(1);        int fla = 0;        for (int i = 0; i <= fb_cnt; i++)        {            if (fb[i] <= rm && fb[i] >= lm)            {                fla = 1;                break;            }        }        if (fla) printf("Yes\n");        else printf("No\n");    }    return 0;}