[HDOJ5876]Sparse Graph(补图最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5876

题意:求一个图的补图中的单源最短路。

题解说:补图上的 BFS 是非常经典的问题。一般的做法是用链表(或者偷懒用 std::set)维护还没 BFS 过的点。当要扩展点 u 的时候,遍历一次还没访问过的点 v,如果 uv 没边,那么将 v 入队。否则将 v 留在未扩展点中。很明显,后者只会发生 m 次,前者只会发生 n 次,所以复杂度是 O(n + m)。

总得说,求补图的最短路就是要存原图,并且需要有一个额外的set来维护未扩展的点集合。

在bfs的时候从队列取出一个点u,访问该点u邻接的点v,假如uv之间有边则补图无边,否则v会入队。

最后的时候要把入队的点从未扩展点集合中删掉。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19 using namespace std;
 20 #define fr first
 21 #define sc second
 22 #define cl clear
 23 #define BUG puts("here!!!")
 24 #define W(a) while(a--)
 25 #define pb(a) push_back(a)
 26 #define Rint(a) scanf("%d", &a)
 27 #define Rll(a) scanf("%I64d", &a)
 28 #define Rs(a) scanf("%s", a)
 29 #define Cin(a) cin >> a
 30 #define FRead() freopen("in", "r", stdin)
 31 #define FWrite() freopen("out", "w", stdout)
 32 #define Rep(i, len) for(int i = 0; i < (len); i++)
 33 #define For(i, a, len) for(int i = (a); i < (len); i++)
 34 #define Cls(a) memset((a), 0, sizeof(a))
 35 #define Clr(a, x) memset((a), (x), sizeof(a))
 36 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 37 #define lrt rt << 1
 38 #define rrt rt << 1 | 1
 39 #define pi 3.14159265359
 40 #define RT return
 41 #define lowbit(x) x & (-x)
 42 #define onecnt(x) __builtin_popcount(x)
 43 typedef long long LL;
 44 typedef long double LD;
 45 typedef unsigned long long ULL;
 46 typedef pair<int, int> pii;
 47 typedef pair<string, int> psi;
 48 typedef pair<LL, LL> pll;
 49 typedef map<string, int> msi;
 50 typedef vector<int> vi;
 51 typedef vector<LL> vl;
 52 typedef vector<vl> vvl;
 53 typedef vector<bool> vb;
 54
 55 const int maxn = 200200;
 56 const int inf = 10000010;
 57 set<int> G[maxn];
 58 set<int> x;
 59 int n, m, s;
 60 int d[maxn];
 61
 62 void bfs(int s) {
 63     Clr(d, -1);
 64     d[s] = 0;
 65     queue<int> q;
 66     q.push(s); x.erase(s);
 67     set<int>::iterator v;
 68     while(!q.empty()) {
 69         int u = q.front(); q.pop();
 70         set<int> y;
 71         for(v = x.begin(); v != x.end(); v++) {
 72             if(G[u].find(*v) == G[u].end()) {
 73                 if(d[*v] == -1) d[*v] = d[u] + 1;
 74                 else d[*v] = min(d[*v], d[u] + 1);
 75                 y.insert(*v);
 76                 q.push(*v);
 77             }
 78         }
 79         for(v = y.begin(); v != y.end(); v++)    {
 80             x.erase(*v);
 81         }
 82     }
 83 }
 84
 85 int main() {
 86     // FRead();
 87     int T, u, v;
 88     Rint(T);
 89     W(T) {
 90         Rint(n); Rint(m);
 91         x.clear();
 92         For(i, 1, n+1) {
 93             x.insert(i);
 94             G[i].clear();
 95         }
 96         Rep(i, m) {
 97             Rint(u); Rint(v);
 98             G[u].insert(v); G[v].insert(u);
 99         }
100         Rint(s);
101         bfs(s);
102         For(i, 1, n+1) {
103             if(i == s) continue;
104             printf("%d%c", d[i], i == n ? ‘\n‘ : ‘ ‘);
105         }
106     }
107     RT 0;
108 }
时间: 2024-10-19 11:44:12

[HDOJ5876]Sparse Graph(补图最短路)的相关文章

HDU 5876 Sparse Graph BFS 最短路

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 n

HDU 5876 Sparse Graph(补图上BFS)

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

hdu5876 Sparse Graph(补图最短路)

题目链接:hdu5876 Sparse Graph 一开始用vector一直TLE,然后就没有然后了.. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<queue> 5 #include<vector> 6 #include<set> 7 using namespace std; 8 9 const int N = 200001; 10

hdu 5876 Sparse Graph 无权图bfs求最短路

Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) 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

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 次

HDU 5876 Sparse Graph

题目:Sparse Graph 链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5876 题意:给出一个图(V<=20万,E<=2万),要求先化为补图(每两个点,原本有边删去边,原本没边添加边),然后问指定点S到其他每个点的最短距离. 思路: 普通的广搜应该解决不了...O(n*m)太大,不会很难,比赛时没做出来有点可惜,当知道过了也进不了时,就安慰了许多. 变化一下思路,从起点出发,因为原本边<=2万,那么大部分的点都已经可以到达了

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

2016大连网络赛 Sparse Graph

Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) 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

HDU 5876 Sparse Graph(补图中求最短路)

http://acm.hdu.edu.cn/showproblem.php?pid=5876 题意: 在补图中求s到其余各个点的最短路. 思路:因为这道题目每条边的距离都是1,所以可以直接用bfs来做. 处理的方法是开两个集合,一个存储当前顶点可以到达的点,另一个存储当前顶点不能到达的点.如果可以到达,那肯定由该顶点到达是最短的,如果不能,那就留着下一次再判. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstr