Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Problem Description
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.
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
Source
题意:
题目给出一个由n个点,m条边组成的图,问如果在n 个点的无向完全图中删除这m 条边,点 s 到其他点的最短路长度是多少。
思路:
如果原图中u与s不相连,那么s->u的距离就是s+1,然后将u放入队列。
每次都找与当前节点不相连的点放入队列,然后求距离,这样求出来的距离肯定是最短的。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <queue>
using namespace std;
const int N=2e5+10;
set<int>G[N], S[2];
set<int>:: iterator it;
queue<int>q;
int ans[N];
void solve(int n, int s){
memset(ans, -1, sizeof(ans));
while(!q.empty()) q.pop();
ans[s]=0;
q.push(s);
int now=0;
for(int i=1; i<=n; i++){
if(i==s) continue;
S[now].insert(i);
}
while(!q.empty()){
s = q.front();q.pop();
S[!now].clear();
for(it=S[now].begin(); it!=S[now].end(); it++){
if(G[s].find(*it)==G[s].end()){
ans[*it] = ans[s]+1;
q.push(*it);
}
else{
S[!now].insert(*it);
}
}
now=!now;
}
}
int main(){
int t;
scanf("%d", &t);
while(t--){
int n, m, u, v, s;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) G[i].clear();
for(int i=0; i<m; i++){
scanf("%d%d", &u, &v);
G[u].insert(v);
G[v].insert(u);
}
scanf("%d", &s);
solve(n, s);
int len=0;
for(int i=1; i<=n; i++){
if(i==s) continue;
ans[len++] = ans[i];
}
for(int i=0; i<len; i++){
if(i==len-1) printf("%d\n", ans[i]);
else printf("%d ", ans[i]);
}
}
return 0;
}