hdu_5876_Sparse Graph(补图BFS)

题目链接:hdu_5876_Sparse Graph

附上叉姐的题解:

1009 Sparse Graph [by ftiasch]

题意:n 个点的无向完全图中删除 m 条边,问点 s 到其他点的最短路长度。

题解:

补图上的 BFS 是非常经典的问题。一般的做法是用链表(或者偷懒用 std::set)维护还没 BFS 过的点。当要扩展点 u 的时候,遍历一次还没访问过的点 v,如果 uv 没边,那么将 v 入队。否则将 v 留在未扩展点中。

很明显,后者只会发生 m 次,前者只会发生 n 次,所以复杂度是 O(n + m)O(n+m).

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4
 5 const int N=2e5+7,M=40010,inf=2e6+7;
 6 int t,n,m,ed,v[M],nxt[M],g[N],x,y,S,d[N];
 7
 8 void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
 9
10 void fuck()
11 {
12     set<int>ta,tb;
13     set<int>::iterator it;
14     queue<int>Q;
15     F(i,1,n)d[i]=inf;
16     d[S]=0,Q.push(S);
17     F(i,1,n)if(i!=S)ta.insert(i);
18     while(!Q.empty())
19     {
20         int now=Q.front();Q.pop();
21         for(int i=g[now];i;i=nxt[i])if(ta.find(v[i])!=ta.end())ta.erase(v[i]),tb.insert(v[i]);
22         for(it=ta.begin();it!=ta.end();it++)Q.push(*it),d[*it]=d[now]+1;
23         ta.swap(tb),tb.clear();
24     }
25     F(i,1,n)if(i!=S)printf("%d%c",d[i]==inf?-1:d[i]," \n"[i==n]);
26 }
27
28 int main()
29 {
30     scanf("%d",&t);
31     while(t--)
32     {
33         scanf("%d%d",&n,&m),ed=0;
34         F(i,1,n)g[i]=0;
35         F(i,1,m)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
36         scanf("%d",&S),fuck();
37     }
38     return 0;
39 }

时间: 2024-12-26 17:45:04

hdu_5876_Sparse Graph(补图BFS)的相关文章

HDU 5876 Sparse Graph(补图上BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5876 题意: 有一个 n 个点无向图,再给你 m 对顶点, 代表着这 m 对顶点之间没有边, 除此之外每两个点之间都有一条边, 且权值为 1.然后还有一个源点 S, 让你计算源点到其他各点之间的最短距离,如果不存在则输出 -1.也就是说让你在所给的图的补图上求源点到其他各点的最短路径. 思路: 补图上求最短路径算是比较经典的题.在这里所求的最短路其实并不需要用到 dijkstra 之类的算法,由于每

hdu 5876 (补图BFS) Sparse Graph

题目:这里 题意: 相当于一开始给一个初始好了的无向完全图给你,然后给让你删除m条边,再给你一个点v,最后问你在剩下的图里从这个点v出发能到达所有边点的最小路径是多少? 一看是所有点的最小路径,一看就觉得是个bfs,记忆化搜一下然后加个优化什么的,由于数据不知道是个什么奇葩而且比赛中还改数据,所以很多人wa的莫名其妙, 过也过的莫名其妙,我虽然过了但觉得有点不靠谱,赛后看了https://async.icpc-camp.org/d/546-2016的题解思路写了一发,总感觉更靠谱一点. 之前自己

HDU 5876:Sparse Graph(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=5876 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 not adjacent in G

[Algorithms] Graph Traversal (BFS and DFS)

Graph is an important data structure and has many important applications. Moreover, grach traversal is key to many graph algorithms. There are two systematic ways to traverse a graph, breadth-first search (BFS) and depth-frist search (DFS). Before fo

POJ-2415 Hike on a Graph (BFS)

Description "Hike on a Graph" is a game that is played on a board on which an undirected graph is drawn. The graph is complete and has all loops, i.e. for any two locations there is exactly one arrow between them. The arrows are coloured. There

Copy Graph(BFS)

自从中午饿得被迫起来吃完了一个午饭之后,就开始做这道题.鉴于之前做过一道Copy List with Random Pointer的题,看了大神的答案之后比自己想的快,就借鉴了那个思想,原先我的想法是用map的key记录原结点的引用,将新建结点的引用存入value,鉴于大神是将copy的结点接在原结点之后再删除,代码简洁得让我震惊啦,而且效率也比我的高,这回用的也是这个思想,就是将copy的结点插入原结点的neighbors的第一个,之后再拆掉...用的BFS...结果..因为BFS之前完全没写

Codeforces 920E(补图BFS)

题意: n(n<=200000)个点的完全图删去了m(m<=200000)条边,求剩下图的连通分量. 分析: 将未访问过的点用一个链表串起来 仍旧进行BFS,每次BFS扩展一个点u的时候,暴力去for链表,如果发现有与u相连的点则该点入队且从链表删除 直至链表为空 我们来分析一下这个的复杂度,首先明显每个点只会删除一次,O(n) 但是一个点会被for很多次,我们发现被for很多次是在原图有边的情况,所以是O(2*m) 总的复杂度O(n+m) 具体在实现过程中,要判断两点是否右边,所以要用一个s

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

hdu1240 三维搜索 bfs dfs都可以

题意,给出一个N,这是这个三空间的大小,然后给出所有面的状况O为空地,X为墙,再给出起始点的三维坐标和终点的坐标,输出到达的步数三维的BFS,很裸的题,不过一定要注意这一题给的坐标x表示列,y表示行,z表示层,实际输入的时候调试一下看看给的坐标是不是跟样例在图中所指的对象一样就行了.http://blog.csdn.net/iaccepted/article/details/23277717bfs讲得好http://iprai.hust.edu.cn/icl2002/algorithm/algo