HDU 5876 关于补图的bfs

1、HDU 5876  Sparse Graph   

2、总结:好题,把STL都过了一遍

题意:n个点组成的完全图,删去m条边,求点s到其余n-1个点的最短距离。

思路:把点分为两个集合,A为所有没有到达过的点,B为当前不可到达的点,每次拓展A中可到过的点加入队列。

#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<set>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=200010,MAX=1000100;

int n,m,dis[N];
vector<int >vec[N];

void bfs(int s)
{
    mes(dis,0);
    set<int >A,B;
    FF(i,1,n)if(i!=s)
        A.insert(i);
    queue<int >qu;
    qu.push(s);
    while(!qu.empty()){
        int u=qu.front();
        qu.pop();
        for(int i=0;i<vec[u].size();i++){      //注:vec从0开始
            int v=vec[u][i];
            if(A.count(v)){
                A.erase(v);     //集合删除、插入
                B.insert(v);
            }
        }
        for(set<int >::iterator it=A.begin();it!=A.end();it++){    //注:it!=A.end()结尾
            dis[*it]=dis[u]+1;      //注:*it
            qu.push(*it);
        }
        A.swap(B);      //集合交换
        B.clear();

    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        FF(i,0,n)vec[i].clear();    //注:vec[i].clear()
        while(m--){
            int u,v;
            scanf("%d%d",&u,&v);
            vec[u].push_back(v);
            vec[v].push_back(u);
        }
        int s;
        scanf("%d",&s);
        bfs(s);
        int flag=0;
        FF(i,1,n){
            if(i!=s){
                if(flag)printf(" ");
                else flag=1;
                printf("%d",dis[i]);
            }
        }
        printf("\n");
    }

    return 0;
}
View Code

 

posted @ 2016-09-28 18:54  v9fly  阅读(200)  评论(0编辑  收藏  举报