Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2680 Accepted Submission(s): 926
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
题意:
求一个补图的单源最短路径。
思路:
首先想到的肯定是dijstra算法,但看他的边数和点数就知道不可能,所以从另一个最短路算法bfs入手,可以说bfs是求补图的经典算法了
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<queue>
#include<vector>
#include<string>
#include<iostream>
#include<set>
using namespace std;
#define Max 200100
#define MOD 530600414
typedef long long LL;
int n,t,m,dp[200100];
set<int>s1,s2;
vector<int>arr[200100];
int main()
{
cin>>t;
while(t--)
{
fill(dp,dp+200001,Max);
s1.clear();
s2.clear();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
arr[i].clear();
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
arr[a].push_back(b);
arr[b].push_back(a);
}
queue<int>q;
int s;
scanf("%d",&s);
q.push(s);
dp[s]=0;
for(int i=1;i<=n;i++)
if(s!=i)
s1.insert(i);
while(!q.empty())
{
int v=q.front();
q.pop();
for(int i=0;i<arr[v].size();i++)
{
int to=arr[v][i];
if(!s1.count(to))continue;
s1.erase(to),s2.insert(to);
}
for(set<int>::iterator it=s1.begin();it!=s1.end();it++)
{
dp[*it]=dp[v]+1;
q.push(*it);
}
s1.swap(s2);
s2.clear();
}
bool f = 0;
for(int i = 1; i <= n; i++) {
if(i != s) {
if(f) printf(" ");
f = 1;
if(dp[i] == Max) printf("-1");
else printf("%d", dp[i]);
}
}
puts("");
}
return 0;
}