您的位置:首页 > 其它

[HDOJ4786]Fibonacci Tree 最小生成树

2015-11-08 20:32 225 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4786

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

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

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>

using namespace std;

typedef struct P {
int u;
int v;
int w;
}P;

bool cmp1(P p1, P p2) {return p1.w < p2.w;}
bool cmp2(P p1, P p2) {return p1.w > p2.w;}
int A, B;

const int maxn = 100010;
int n, m, cnt;
int pre[maxn];
int fib[maxn];
P e[maxn];

int find(int x) {
return x == pre[x] ? pre[x] : pre[x] = find(pre[x]);
}

bool unite(int x, int y) {
x = find(x);
y = find(y);
if(x != y) {
pre[x] = y;
return 1;
}
return 0;
}

void init() {
for(int i = 0; i < maxn; i++) {
pre[i] = i;
}
}

void clear() {
init();
memset(e, 0, sizeof(e));
A = 0, B = 0;
cnt = 0;
}

int main() {
// freopen("in", "r", stdin);
int T;
fib[0] = 0, fib[1] = 1, fib[2] = 1;
for(int i = 3; i <= 26; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
scanf("%d", &T);
for(int _ = 1; _ <= T; _++) {
printf("Case #%d: ", _);
clear();
scanf("%d %d", &n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
}
sort(e, e+m, cmp1);
for(int i = 0; i < m; i++) {
if(unite(e[i].u, e[i].v)) {
A += e[i].w;
cnt++;
}
}
if(cnt != n - 1) printf("No\n");
else {
init();
sort(e, e+m, cmp2);
for(int i = 0; i < m; i++) {
if(unite(e[i].u, e[i].v)) {
B += e[i].w;
cnt++;
}
}
int flag = 0;
for(int i = 1; i <= 25; i++) {
if(fib[i] <= B && fib[i] >= A) {
flag = 1;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
}


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

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>

using namespace std;

typedef struct P {
int u;
int v;
int w;
}P;

bool cmp1(P p1, P p2) {return p1.w < p2.w;}
bool cmp2(P p1, P p2) {return p1.w > p2.w;}
int A, B;

const int maxn = 100010;
int n, m, cnt;
int pre[maxn];
int fib[maxn];
P e[maxn];

int find(int x) {
return x == pre[x] ? pre[x] : pre[x] = find(pre[x]);
}

bool unite(int x, int y) {
x = find(x);
y = find(y);
if(x != y) {
pre[x] = y;
return 1;
}
return 0;
}

void init() {
for(int i = 0; i < maxn; i++) {
pre[i] = i;
}
}

void clear() {
init();
memset(e, 0, sizeof(e));
A = 0, B = 0;
cnt = 0;
}

void __FIB__() {
fib[0]=0,fib[1]=1,fib[2]=1,fib[3]=2,fib[4]=3,fib[5]=5,
fib[6]=8,fib[7]=13,fib[8]=21,fib[9]=34,fib[10]=55,
fib[11]=89,fib[12]=144,fib[13]=233,fib[14]=377,
fib[15]=610,fib[16]=987,fib[17]=1597,fib[18]=2584,
fib[19]=4181,fib[20]=6765,fib[21]=10946,fib[22]=17711,
fib[23]=28657,fib[24]=46368,fib[25]=75025;
}

int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
int T;
__FIB__();
scanf("%d", &T);
for(int _ = 1; _ <= T; _++) {
printf("Case #%d: ", _);
clear();
scanf("%d %d", &n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);
}
sort(e, e+m, cmp1);
for(int i = 0; i < m; i++) {
if(unite(e[i].u, e[i].v)) {
A += e[i].w;
cnt++;
}
}
if(cnt != n - 1) printf("No\n");
else {
init();
for(int i = m; i >= 0; i--) {
if(unite(e[i].u, e[i].v)) {
B += e[i].w;
cnt++;
}
}
int flag = 0;
int ll = 1, rr = 25;
while(ll < rr) {
int mm = (ll + rr) >> 1;
if(fib[mm] <= B && fib[mm] >= A) {
flag = 1;
break;
}
else if(fib[mm] > B) rr = mm;
else if(fib[mm] < A) ll = mm + 1;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: