Sparse Graph
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
notadjacent 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
题意:给出一个图,问你补图中s点到其他各个点的距离,到不了为-1.
思路:用两个队列,一个来跑bfs,另一个存点.先把所有元素压进队列all,s点压进q,每次从q中取一个点now,把与之相连的边做个标记,然后从all里一个一个取点,如果取出来的点未标记,说明补图中now可以到达该点(当然距离肯定也是最短的,因为每条边长度一样嘛),就把该点压入q中,因为给的原图很稀疏,所以这样也跑不了几次.
网上大都用set来做,这样做的复杂度比set略低,因为set每次也是遍历整个容器,但是他的查找的复杂度是略高的.
代码:
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mod 1000000007 using namespace std; typedef long long ll; const int maxn = 1e6+5; const double esp = 1e-12; const int ff = 0x3f3f3f3f; map<int,int>::iterator it; struct node { int v; int ne; } edge[maxn]; int n,m,s; int len,flag; int dis[maxn]; int head[maxn]; int vis[maxn]; void add(int u,int v) { edge[len].v = v; edge[len].ne = head[u]; head[u] = len++; } void solve() { queue<int> q; queue<int> all; for(int i = 1;i<= n;i++) if(i!= s) all.push(i); int mk = 1,cnt; q.push(s); dis[s] = 0; while(!q.empty()) { int now = q.front(); q.pop(); for(int i = head[now];i!= -1;i = edge[i].ne) vis[edge[i].v] = mk; cnt = all.size(); while(cnt--) { int id = all.front(); all.pop(); if(vis[id] == mk) all.push(id); else { dis[id] = dis[now]+1; q.push(id); } } mk++; } for(int i = 1;i<= n;i++) { if(i == s) continue; if(dis[i]> maxn) printf("-1"); else printf("%d",dis[i]); if(i == n-1&&s == n||i == n) continue; else printf(" "); } printf("\n"); } void init() { len = 0; mem(dis,ff); mem(vis,0); mem(head,-1); } int main() { int t; cin>>t; while(t--) { init(); scanf("%d %d",&n,&m); for(int i = 1;i<= m;i++) { int x,y; scanf("%d %d",&x,&y); add(x,y); add(y,x); } scanf("%d",&s); solve(); } return 0; }