[HDU4786]Fibonacci Tree

剛讀題還以爲是WJMZBMR出的tree(bzoj2654)...

其實只用分別把黑邊放在前面 白邊放在前面做mst,統計兩次用的白邊數量,看看這個區間內是否有fbi數就可以了

代碼寫的很挫而且由於數組開小RE了好幾次-_-#


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int MAX=100010;
vector<int> WS,wt,bs,bt;
int fbi[MAX],maxf,uni[MAX],us[MAX],ut[MAX],uc[MAX],N,M,f1;
void pre()
{
    memset(fbi,0,sizeof(fbi));
    fbi[1]=1;
    fbi[2]=2;
    maxf=2;
    while (fbi[maxf]<=100000)
    {
        maxf++;
        fbi[maxf]=fbi[maxf-1]+fbi[maxf-2];
    }
}
int find(int x)
{
    int t=x,r;
    while(x!=uni[x]) x=uni[x];
    while(t!=uni[t])
    {
        r=uni[t];
        uni[t]=x;
        t=r;
    }
    return x;
}
void union1(int x,int y)
{
    int a=find(x),b=find(y);
    uni[a]=uni[b];
}
int mst()
{
    memset(uni,0,sizeof(uni));
    for (int i=1; i<=N; i++)
        uni[i]=i;
    int ans=0,num=0;
    for (int i=1; i<=M; i++)
    {
        if (num==N-1) return ans;
        if (find(us[i])!=find(ut[i]))
        {
            union1(us[i],ut[i]);
            if (uc[i]==1) ans++;
            num++;
        }
    }
    if (num!=N-1) f1=false;
    return ans;
}
int main()
{
    freopen("in.in","r",stdin);
    pre();
    int T;
    scanf("%d",&T);
    for (int Ti=1; Ti<=T; Ti++)
    {
        scanf("%d%d",&N,&M);
        int s,t,c;
        for (int i=1; i<=M; i++)
        {
            scanf("%d%d%d",&s,&t,&c);
            if (c==1)
            {
                WS.push_back(s);
                wt.push_back(t);
            }
            else
            {
                bs.push_back(s);
                bt.push_back(t);
            }
        }
        for (int i=0; i<bs.size(); i++)
        {
            us[i+1]=bs[i];
            ut[i+1]=bt[i];
            uc[i+1]=0;
        }
        f1=true;
        for (int i=0; i<WS.size(); i++)
        {
            us[i+bs.size()+1]=WS[i];
            ut[i+bt.size()+1]=wt[i];
            uc[i+bt.size()+1]=1;
        }
        int l=mst();
        for (int i=0; i<WS.size(); i++)
        {
            us[i+1]=WS[i];
            ut[i+1]=wt[i];
            uc[i+1]=1;
        }
        for (int i=0; i<bs.size(); i++)
        {
            us[i+WS.size()+1]=bs[i];
            ut[i+wt.size()+1]=bt[i];
            uc[i+wt.size()+1]=0;
        }
        int r=mst();
        bool flag=false;
        for (int i=1; i<=maxf; i++)
            if (fbi[i]>=l&&fbi[i]<=r)
            {
                flag=true;
                break;
            }
        printf("Case #%d: ",Ti);
        if (flag&&f1) printf("Yes\n");
        else printf("No\n");
        WS.clear();
        wt.clear();
        bs.clear();
        bt.clear();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章