hdu5877
题意:T组样例,没组n个点,m条边, 再输入一个点k,k<n,求k到补图中各点的最短路。
题解:用set 去存不相邻的点,然后累计增加长度,
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
const int INF=0x7f7f7f;
const int maxn=200005;
struct Edge{
int to,from;
}edge[maxn];
int head[maxn],top;
int n,m;
int dis[maxn];
int into(){
memset(head,-1,sizeof(head));
memset(dis,INF,sizeof(dis));
top=0;
}
void add(int u,int v){
edge[top].to=u;
edge[top].from=head[v];
head[v]=top++;
}
int bfs(int st){
set<int> s1;
set<int> s2;
set<int>::iterator it;
//除了st 计算的这个点其他都收到s1 集合里
for(int i=1;i<=n;i++)
if(i!=st)
s1.insert(i);
queue<int>q;
q.push(st);
dis[st]=0;//只能在st的基础上加
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].from){
int to=edge[i].to;
//s1集合里没有就跳过
if(!s1.count(to))
continue;
//s1集合里有,把这个点放到 s2里面
//s1集合里有,说明点u和这些点相邻
// 但是我们要计算不相邻的,所以拿出来单独考虑
s1.erase(to);
s2.insert(to);
}
//s1中现在存的是 和u点不相邻的数
//s2中现在存的是和u相邻的数
for(it=s1.begin();it!=s1.end();it++){
q.push(*it);
//点到u的距离+1
dis[*it]=dis[u]+1;
}
//换回去,再次比较
s1.swap(s2);
s2.clear();
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
into();
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
int stt;
scanf("%d",&stt);
bfs(stt);
// 输出结果
for(int i=1;i<=n;i++){
if(i==stt)
continue;
//i没走过
if(dis[i]==INF)
printf("-1");
else
printf("%d",dis[i]);
if(i==n)
printf("\n");
else printf(" ");
}
}
return 0;
}