题意:
给出原图,在补图上求其S点到达各个点最短距离
思路:
保留所有的待更新的点,从S点开始,每次松弛一点(与S无边),之后把这个点从当更新的数组中删除
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <set>
using namespace std;
const int maxn=200005;
set<int> vec[maxn];
set<int> save;
int ans[maxn];
int n,m;
void bfs(int s)
{
queue<int> q;
q.push(s);
save.clear();
for(int i=1; i<=n; i++)
{
if(i!=s) save.insert(i);
}
ans[s]=0;
set<int> del;
while(!q.empty())
{
del.clear();
int now=q.front();
q.pop();
for(set<int> ::iterator it=save.begin(); it!=save.end(); ++it)
{
if(!vec[now].count(*it))
{
if(ans[*it]==-1)
{
ans[*it]=ans[now]+1;
del.insert(*it);
q.push(*it);
}
}
}
for(set<int>:: iterator it=del.begin(); it!=del.end(); ++it )
{
save.erase(*it);
}
}
}
int main()
{
int t;
while(~scanf("%d",&t))
{
while(t--)
{
memset(ans,-1,sizeof(ans));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
vec[i].clear();
}
for(int i=1; i<=m; i++)
{
int u,v,w=1;
scanf("%d%d ",&u,&v);
vec[u].insert(v);
vec[v].insert(u);
}
int s;
scanf("%d",&s);
bfs(s);
for(int i = 1; i <= n; i++)
{
if(i == s) continue;
printf("%d", ans[i]);
if(s == n)
{
if(i != n - 1) printf(" ");
else printf("\n");
}
else
{
if(i != n) printf(" ");
else printf("\n");
}
}
}
}
}