Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 110 Accepted Submission(s): 40
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.
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
题意:给一张图,求其补图的某源点的最短路。
由于点很多但是边很少所以不可以对其补图进行操作,建立原图,刚开始时和源点无边的点肯定补图中最短路径是1,并将这些点存入一个集合,下次再判断这这集合的点如果和其他的某个点如果没有一条边相连,这里用队列可以边记录边将集合中的点清空,则该点距离是2,并加入集合。。。接着继续该步骤直到集合空。
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 200010;
vector<int> ans;
queue<int> que;
int result[maxn];
int flag[maxn];
bool vis[maxn];
int main()
{
int t, n, m, s, step;
scanf("%d", &t);
while (t--)
{
ans.clear();
memset(vis, false, sizeof(vis));
while (!que.empty()) que.pop();
scanf("%d%d", &n, &m);
int x, y;
vector<int> datas[maxn];
for (int i = 0; i < m; ++i)
{
scanf("%d%d", &x, &y);
datas[x].push_back(y);
datas[y].push_back(x);
}
scanf("%d", &s);
que.push(s);
flag[s] = true;
step = 0;
int cnt = 0, tmp;
while(!que.empty())
{
memset(flag, 0, sizeof(flag));
++step;
tmp = que.front(); que.pop();
cnt = 0;
while(1)
{
cnt++;
for (int i = 0; i < datas[tmp].size(); ++i) flag[datas[tmp][i]]++;
if (!que.empty())
{
tmp = que.front();
que.pop();
}
else
{
break;
}
}
for (int i = 1; i <= n; ++i)
{
if (cnt > flag[i])//表示i点不是和集合里所有点都相连,即补图中可以有一条边相连,在上个距离基础上加1即最短路
{
if (!vis[i])
{
que.push(i);
vis[i] = true;
result[i] = step;
}
}
}
}
for (int i = 1; i <= n; ++i)
{
if (i != s)
{
if (vis[i])
{
ans.push_back(result[i]);
}
else
ans.push_back(-1);
}
}
int len = ans.size() - 1;
for (int i = 0; i < len; ++i)
printf("%d ", ans[i]);
printf("%d\n", ans[len]);
}
return 0;
}
Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 110 Accepted Submission(s): 40
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
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 200010;
vector<int> ans;
queue<int> que;
int result[maxn];
int flag[maxn];
bool vis[maxn];
int main()
{
int t, n, m, s, step;
scanf("%d", &t);
while (t--)
{
ans.clear();
memset(vis, false, sizeof(vis));
while (!que.empty()) que.pop();
scanf("%d%d", &n, &m);
int x, y;
vector<int> datas[maxn];
for (int i = 0; i < m; ++i)
{
scanf("%d%d", &x, &y);
datas[x].push_back(y);
datas[y].push_back(x);
}
scanf("%d", &s);
que.push(s);
flag[s] = true;
step = 0;
int cnt = 0, tmp;
while(!que.empty())
{
memset(flag, 0, sizeof(flag));
++step;
tmp = que.front(); que.pop();
cnt = 0;
while(1)
{
cnt++;
for (int i = 0; i < datas[tmp].size(); ++i) flag[datas[tmp][i]]++;
if (!que.empty())
{
tmp = que.front();
que.pop();
}
else
{
break;
}
}
for (int i = 1; i <= n; ++i)
{
if (cnt > flag[i])//表示i点不是和集合里所有点都相连,即补图中可以有一条边相连,在上个距离基础上加1即最短路
{
if (!vis[i])
{
que.push(i);
vis[i] = true;
result[i] = step;
}
}
}
}
for (int i = 1; i <= n; ++i)
{
if (i != s)
{
if (vis[i])
{
ans.push_back(result[i]);
}
else
ans.push_back(-1);
}
}
int len = ans.size() - 1;
for (int i = 0; i < len; ++i)
printf("%d ", ans[i]);
printf("%d\n", ans[len]);
}
return 0;
}