hdu4786
最小生成树的变形题,求一遍最小,求一遍最大,在从此区间是否含有斐波那契数,别忘了并查集,因为可能不连通。
后来想其实不难,场上出不来的原还是对最小生成数不熟练,基础薄弱。!
#include<bits/stdc++.h>
using namespace std;
int par[100100];
int rank_[101000];
struct edge {
int u,v,cost;
};
int n,m;
int init(int n){
for(int i=0;i<=n;i++) {
par[i]=i;
rank_[i]=0;
}
}
bool comp(const edge& e1,const edge& e2){
return e1.cost > e2.cost;
}
bool comp2(const edge& e1,const edge& e2){
return e1.cost < e2.cost;
}
edge es[100100];
int find_(int x){
if(par[x]==x) return x;
else return par[x]=find_(par[x]);
}
void unite(int x,int y){
x=find_(x);
y=find_(y);
if(x==y) return ;
if(rank_[x]<rank_[y]){
par[x]=y;
}else {
par[y]=x;
if(rank_[x]==rank_[y]) rank_[x]++;
}
}
bool same(int x,int y){
return find_(x)==find_(y);
}
int kruskal(){
sort(es,es+m,comp);
init(n);
int res=0;
for(int i=0;i<m;i++){
edge e=es[i];
if(!same(e.u,e.v)){
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}
int kruskal2(){
sort(es,es+m,comp2);
init(n);
int res=0;
for(int i=0;i<m;i++){
edge e=es[i];
if(!same(e.u,e.v)){
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}
const int maxn = 1e5 + 100;
int main()
{
int F[maxn];
int tmp[maxn];
memset(tmp,0,sizeof(tmp));
memset(F,0,sizeof(F));
tmp[0] = 1; tmp[1] = 2;
F[1] = 1;
F[2] = 1;
for(int i = 2; tmp[i-2] + tmp[i-1] < maxn; ++i)
{
tmp[i] = tmp[i-2] + tmp[i-1];
F[tmp[i]] = 1;
}
int t,kase=0;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int flag=0;
init(n);
for(int i=0;i<m;i++){
scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);
unite(es[i].u,es[i].v);
}
int cnt=0;
for(int i=1;i<=n;i++) if(par[i]==i) ++cnt;
int o=0;
printf("Case #%d: ",++kase);
if(cnt==1) {
int q = kruskal2();
int p = kruskal();
for(int i=q;i<=p;i++)
if(F[i]) {
o=1; break;
}
}
if(o) printf("Yes"); else printf("No");
printf("\n");
}
return 0;
}