其实bfs本身不难,甚至不需要去学习,只要知道它的特性就可以写出来了。往往,bfs都是用递归做的。递归比循环更容易timeout。所以这次遇到一题bfs,卡时间的就悲剧了。

PAT1076

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define N (1000+10)
#define INF (1<<30)
vector<int> Map[N];
int vis[N];
int Hash[N];
int n,m;
int res,ans[N];
void bfs(vector<int> vi,int cnt)
{
    int nsize = vi.size();
    if(nsize==0) return;
    if(cnt == m+1){return;}
    ++cnt;
    vector<int> vnext;
    for(int i=0;i<nsize;++i)
    {
        int val = vi[i];
        vis[val] = 1;
        //printf("[%d] ",vi[i]+1);
        int nMapSize = Map[vi[i]].size();
        if(!Hash[val])
        {
            ++res;
            Hash[val] = 1;
        }
        for(int j=0;j<nMapSize;++j)
        if(vis[Map[val][j]]==0 && Hash[Map[val][j]]==0)
        {
            vnext.push_back(Map[val][j]);
        }
    }
    //printf("\n");
    if(vnext.size());
        bfs(vnext,cnt);
    for(int i=0;i<nsize;++i)
        vis[vi[i]] = 0;
}
int l;
void bfs2(int k)
{
    queue<int> qi;
    qi.push(k);
    int presize = 1;
    while(!qi.empty())
    {
        int val = qi.front();
        qi.pop();
        ++res;
        vis[val] = 1;
        for(int i=0;i<Map[val].size();++i)
        {
            int mapval = Map[val][i];
            if(vis[mapval]==0)
            {
                vis[mapval] = 1;
                qi.push(mapval);
                //printf("[%d] ",mapval+1);
            }
        }
        --presize;
        if(presize==0)
        {
            //printf("\n");
            ++l;
            presize = qi.size();
        }
        if(l==m+1) break;
    }

    res = res > 0 ? res-1 : 0;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;++i)
    {
        int k;
        scanf("%d",&k);
        for(int j=0;j<k;++j)
        {
            int s=i,e;
            scanf("%d",&e);
            --e;
            //反向
            Map[e].push_back(s);
        }
    }
    int k;
    scanf("%d",&k);
    for(int i=0;i<k;++i)
    {
        int s;
        scanf("%d",&s);
        --s;
        /*vector<int> vi;
        vi.push_back(s);
        res = 0;
        memset(Hash,0,sizeof(int)*(n+10));
        memset(vis,0,sizeof(vis));
        Hash[s] = 1;
        bfs(vi,0);
        */
        res = 0;
        l = 0;
        memset(vis,0,sizeof(vis));
        bfs2(s);
        printf("%d\n",res);
    }
    return 0;
}
View Code