hdu_5876_Sparse Graph(补图BFS)

题目链接:hdu_5876_Sparse Graph

附上叉姐的题解:

1009 Sparse Graph [by ftiasch]

题意:n 个点的无向完全图中删除 m 条边,问点 s 到其他点的最短路长度。

题解:

补图上的 BFS 是非常经典的问题。一般的做法是用链表(或者偷懒用 std::set)维护还没 BFS 过的点。当要扩展点 u 的时候,遍历一次还没访问过的点 v,如果 uv 没边,那么将 v 入队。否则将 v 留在未扩展点中。

很明显,后者只会发生 m 次,前者只会发生 n 次,所以复杂度是 O(n + m)O(n+m).

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4 
 5 const int N=2e5+7,M=40010,inf=2e6+7;
 6 int t,n,m,ed,v[M],nxt[M],g[N],x,y,S,d[N];
 7 
 8 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
 9 
10 void fuck()
11 {
12     set<int>ta,tb;
13     set<int>::iterator it;
14     queue<int>Q;
15     F(i,1,n)d[i]=inf;
16     d[S]=0,Q.push(S);
17     F(i,1,n)if(i!=S)ta.insert(i);
18     while(!Q.empty())
19     {
20         int now=Q.front();Q.pop();
21         for(int i=g[now];i;i=nxt[i])if(ta.find(v[i])!=ta.end())ta.erase(v[i]),tb.insert(v[i]);
22         for(it=ta.begin();it!=ta.end();it++)Q.push(*it),d[*it]=d[now]+1;
23         ta.swap(tb),tb.clear();
24     }
25     F(i,1,n)if(i!=S)printf("%d%c",d[i]==inf?-1:d[i]," \n"[i==n]);
26 }
27 
28 int main()
29 {
30     scanf("%d",&t);
31     while(t--)
32     {
33         scanf("%d%d",&n,&m),ed=0;
34         F(i,1,n)g[i]=0;
35         F(i,1,m)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
36         scanf("%d",&S),fuck();
37     }
38     return 0;
39 }
View Code

 

posted @ 2016-09-10 21:11  bin_gege  阅读(365)  评论(0编辑  收藏  举报