2015 Multi-University Training Contest 3 || HDU 5325 Crazy Bobo || 類似bfs

hdu 5325 Crazy Bobo
題意:

  • 給出n個帶有權值w[i]的點,n-1條邊,一棵以x爲根的子樹,這棵子樹是滿足每一條路徑中包含x,其中x的權值最小,且這條路徑的權值是單調遞增的。求所有x子樹中包含點的數目最多的點數。

思路:

  • 這裏寫圖片描述

  • 官方題解好簡單,幾句話就搞定了,按照這個思路,我先做好了預處理,然後bfs,然後就是tle無數。最後才明白,有個類似(tm就是累死)。仔細想了想,其實純bfs是有很多多餘的操作(如果數據給力的話,當然實際也給力,不然也不會tle了),看了標程後,。。。直接對邊中點權值較大的計數,然後直接通過計數的次數來進行bfs,節省了很多的計算步驟。這個是真心沒想到。

時間複雜度:

  1. O(n)

不多說,上代碼:

/* ***********************************************
Author        :Ilovezilian
Created Time  :2015/7/29 9:59:15
File Name     :1010.cpp
 ************************************************ */

#include <bits/stdc++.h>
#define fi(i,n) for(int i = 0; i < n; i ++)
#define fin(i,n1,n2) for(int i = n1; i < n2; i ++)
#define ll long long
#define INF 0x0x7fffffff
using namespace std;
const int N = 500050, mod = 1e9+7;

int W[N];
vector<int> e[N];
int n, ans, cnt[N],vis[N];

void bfs()
{
    queue<int > q;
    fin(i,1,n+1) if(!vis[i]) q.push(i);
    ans = 0;
    while(!q.empty())
    {
        int u = q.front(); q.pop();
        ans = max(ans, cnt[u]);
        for(int j = 0; j < e[u].size(); j ++)
        {
            int v = e[u][j];
            cnt[v] += cnt[u];
            vis[v] --;
            if(vis[v] == 0) q.push(v);
        }
    }
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    //freopen("1010.in","r",stdin);
    //freopen("my.out","w",stdout);

    while(cin>>n)
    {
        fill(cnt + 0, cnt + n + 1, 1);
        memset(vis, 0, sizeof(vis));
        fi(i, n + 1) e[i].clear();
        fi(i,n) cin>>W[i+1];

        int x, y;
        fi(i,n-1) 
        {
            cin>>x>>y;
            if(W[x] > W[y]) e[x].push_back(y), vis[y] ++;
            else e[y].push_back(x), vis[x] ++;
        }

        bfs();

        //fin(i,1, n + 1) printf("cnt[%d] = %d\n", i, cnt[i]);

        cout<<ans<<'\n';
        cout<<flush;
    }

//  printf("Time used = %.2f\n", (double) clock() / CLOCKS_PER_SEC);
    return 0;
}

超時代碼:

/* ***********************************************
Author        :Ilovezilian
Created Time  :2015/7/29 9:59:15
File Name     :1010.cpp
************************************************ */

#include <bits/stdc++.h>
#define fi(i,n) for(int i = 0; i < n; i ++)
#define fin(i,n1,n2) for(int i = n1; i < n2; i ++)
#define ll long long
#define INF 0x0x7fffffff
using namespace std;
const int N = 500050, mod = 1e9+7;

pair<int, int> pr[N];
vector<int> e[N];
bool vis[N];
int n, ans, cnt[N];

void bfs()
{
    memset(vis, 0, sizeof(vis));
    ans = 0;
    queue<int > q;
    for(int i = 0; i < n; i ++) if(!vis[pr[i].second])
    {
        while(!q.empty()) q.pop();
        int u = pr[i].second, cnt = 1;
        q.push(u);
        vis[u] = 1;
        //printf("%d\n", q.empty());
        //printf("u = %d\n", u);
        while(!q.empty())
        {
            for(int j = 0; j < e[u].size(); j ++)
            {
                int v = e[u][j];
                q.push(v);
                vis[v] = 1;
            }
            cnt += e[u].size();
        //  printf("u1 = %d\n", u);
            q.pop();
            u = q.front();
        }
        ans = max(ans, cnt);
    }
    return ;
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
   // freopen("1010.in","r",stdin);
    //freopen("my.out","w",stdout);
    //printf("Time = %.2f\n", (double) clock() / CLOCKS_PER_SEC);
    time_t st, ed, t;
    while(cin>>n)
    {
        fi(i, n + 1) e[i].clear();
        int w;
        fi(i,n) 
        {
            cin>>w;
            pr[i] = make_pair(w, i+1);
        }

        int x, y;
        fi(i,n-1) 
        {
            cin>>x>>y;
            if(pr[x-1].first < pr[y-1].first) e[x].push_back(y);
            else e[y].push_back(x);
        }
/*
        fin(i,1,n+1)
        {
            printf("e[%d] = ", i);
            fi(j,e[i].size()) printf(" %d ", e[i][j]); 
            puts("");
        }
*/

        sort(pr, pr + n);
        //fi(i,n) printf("pair[%d].first = %d pair[%d].second = %d\n", i, pr[i].first, i, pr[i].second);

        bfs();

        cout<<ans<<'\n';
    }

    //printf("Time used = %.2f\n", (double) clock() / CLOCKS_PER_SEC);
    return 0;
}


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