Sparse Graph HDU - 5876
In graph theory, the complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if and only if they are not adjacent in G.
Now you are given an undirected graph G of N nodes and M bidirectional edges of unit length. Consider the complement of G, i.e., H. For a given vertex S on H, you are required to compute the shortest distances from S to all N−1
other vertices.
Input
There are multiple test cases. The first line of input is an integer T(1≤T<35) denoting the number of test cases. For each test case, the first line contains two integers N(2≤N≤200000) and M(0≤M≤20000). The following M lines each contains two distinct integers u,v(1≤u,v≤N) denoting an edge. And S (1≤S≤N)
is given on the last line.
Output
For each of T test cases, print a single line consisting of N−1 space separated integers, denoting shortest distances of the remaining N−1 vertices from S
(if a vertex cannot be reached from S, output “-1” (without quotes) instead) in ascending order of vertex number.
Sample Input
1
2 0
1
Sample Output
1
题意:
给一个图,和起点s,求s在补图中各个点的最短路
分析:
可以把原图以set的形式存到一个邻接表里,然后补图就可以通过判断set里的点来较快的得到边。
这样的话广搜每次扩展都要遍历一遍所有的节点,如若不优化一定超时。考虑每次bfs把所有点存到set里,每次走完的点就从set里删除,这样就不用每次都遍历所有的点了。可以水过。要注意输出格式
code:
#include <bits/stdc++.h>
using namespace std;
int n,m,s;
set<int>mp[200010];//存原图
set<int>book;//存待访问的点
int ans[200100];//存答案最短路
void bfs(int s){
ans[s] = 0;
queue<int> q;
q.push(s);
int i;
for(i = 1; i <= n; i++){
if(i != s) book.insert(i);//将除s外的点存入作为待访问的点表示还没到达
}
set<int> del;//要删除的点,已经到达了
while(!q.empty()){
int now = q.front();
q.pop();
set<int>::iterator it;
del.clear();//每次进行新的扩展要先清空要删除的点,因为上一次已经删了,再删会出错
for(it = book.begin(); it != book.end(); it++){
if(!mp[now].count(*it)){//如果原图不到达这个点说明可以走(补图嘛)
if(ans[*it] == -1){//如果距离还为初始状态
ans[*it] = ans[now] + 1;//距离为到达当前点的距离+1
del.insert(*it);//此时说明我们到达了这点,加入队列
q.push(*it);//并将到达的新点加入删除set中以后不用再看这个点了
}
}
}
for(it = del.begin(); it != del.end(); it++){//扩展完后,统一删除点
book.erase(*it);
}
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int i,j,x,y;
memset(ans,-1,sizeof(ans));
for(int i = 0; i <= n; i++){
mp[i].clear();
}
book.clear();
for(int i = 0; i < m; i++){//存图
scanf("%d%d",&x,&y);
mp[x].insert(y);
mp[y].insert(x);
}
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) putchar(' ');
else putchar('\n');
}
else{
if(i != n) putchar(' ');
else putchar('\n');
}
}
}
return 0;
}