解题思路;
因为权值为1,所以用bfs来求最短路,因为是补图,直接建图是不行的,所以只能保存下来,再查询,用set来维护可以到达的点和不可以到达的点,最后交换,确保每个点只访问一次。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include <queue>
#include <vector>
#include <set >
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
vector<int>G[200005];
int d[200005];
set<int> s;
const int inf=1e9;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
s.clear();
scanf("%d%d",&n,&m);
int u,v;
for(int i=1;i<=n;i++)
{
G[i].clear();
d[i]=inf;
s.insert(i);
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
int S;
scanf("%d",&S);
queue<int> q;
q.push(S);
set<int>::iterator it;
d[S]=0;
while(!q.empty())
{
set<int> b;
int now=q.front();
q.pop();
s.erase(now);
int len=G[now].size();
for(int i=0;i<len;i++)
{
int t=G[now][i];
if(s.count(t))
{
s.erase(t);
b.insert(t);
}
}
for(it=s.begin();it!=s.end();it++)
{
d[*it]=d[now]+1;
q.push(*it);
}
s.swap(b);
}
for(int i=1,j=1;i<=n;i++)
{
if(i!=S)
{
if(j!=n-1)
{
printf("%d ",d[i]==inf?-1:d[i]);
}
else
printf("%d\n",d[i]==inf?-1:d[i]);
j++;
}
}
}
return 0;
}