HDU 5876 补图求最短路
2016-09-10 20:15
399 查看
Sparse Graph
[b]Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 110 Accepted Submission(s): 40
[/b]
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
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.
[align=left]Sample Input[/align]
1
2 0
1
[align=left]Sample Output[/align]
1
[align=left]Source[/align]
2016 ACM/ICPC Asia Regional Dalian Online
[align=left]Recommend[/align]
wange2014 | We have carefully selected several similar problems for you: 5877 5875 5874 5873 5872
每次扩展都选择与u无相邻的边。fb保存的是未扩展的。
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
const int INF=0x7f7f7f;
const int N=2e5+10000;
struct edge
{
int next,v,w;
} edge
;
int cnt,head
;
long long dis
;
void init()
{
memset(head,-1,sizeof(head));
memset(dis,INF,sizeof(dis));
cnt=0;
}
void add(int u,int v,int w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void bfs(int st,int ed)
{
queue<int>q;
q.push(st);
set<int>fa,fb;
int i;
dis[st]=0;
for(i=1; i<=ed; i++)
{
if(i!=st)
fa.insert(i);
}
while(!q.empty())
{
int u=q.front();
q.pop();
for(i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(!fa.count(v))
continue;
fa.erase(v);
fb.insert(v);
}
for(set<int>:: iterator it=fa.begin(); it!=fa.end(); it++)
{
q.push(*it);
dis[*it]=dis[u]+1;
}
fa.swap(fb);
fb.clear();
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,s;
cin>>n>>m;
init();
for(int i=1; i<=m; i++)
{
int u,v;
cin>>u>>v;
add(u,v,1);
add(v,u,1);
}
cin>>s;
bfs(s,n);
int ok=0;
for(int i=1; i<=n; i++)
{
if(i==s)
continue;
if(ok)
cout<<" ";
ok=1;
if(dis[i]==INF)
cout<<-1;
else
cout<<dis[i];
}
cout<<endl;
}
return 0;
}
相关文章推荐
- 递归
- 笔记③:POJ Roadblocks 次短路问题代码解析(优先队列逆序排列两种方法)
- 笔记②:并查集算法解析及其高级运用(POJ1182 食物链代码解析)
- 算法基础篇:常见图论最短路算法(Bellman-Ford→SPFA→Dijkstra Floyd-Warshall )入门以及代码解析
- 巩固基础篇:经典二分查找模型及其应用
- 浅谈变换(证明)→反演→莫比乌斯反演→线筛运用
- 中国剩余定理的解析及记忆(扩展欧几里得算法的运用)
- 素数表的快速建立,合数分解,1-2^31内某个长度小于10w的区间素数筛选的三个模板及解析
- 线段树3种基础模型的理解和记忆(任意区间求和,任意区间的所有数加上相同数(懒操作),任意区间所有数变成同一个值再求和)
- ZOJ 1610 Count the Colors 多次更新一次查询,只需要一一标记
- POJ 3264 Balanced Lineup 查询区间最大最小值 基础线状树水题
- HDU 1698 Just a Hook 线状树经典模型之区间变动bool标记,上下同时更新
- POJ 3468 A Simple Problem with Integers(线状树经典模型之lazy操作)
- POJ 2251 Dungeon Master 比较有趣的三维迷宫bfs搜索路径
- 论Acmer的自我修养 (算法学习目标和推荐题目)
- HDU 1260 Tickets (很简单的基础DP题,找到状态转移方程就直接AC了)
- HDU 1176 免费馅饼 (类似于数塔DP的题目,注意边界条件,细节处理)
- HDU 1114 Piggy-Bank (完全背包水题,但注意一下时间输出)
- HDU 1087 Super Jumping!Jumping!Jumping求连续上升子序列的最大和值 (解析)
- HDU 1069 Monkey and Banana 对比优先权的设置和排序问题(解析)