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

题意:

  有一个 n 个点无向图,再给你 m 对顶点, 代表着这 m 对顶点之间没有边, 除此之外每两个点之间都有一条边, 且权值为 1.然后还有一个源点 S, 让你计算源点到其他各点之间的最短距离,如果不存在则输出 -1.也就是说让你在所给的图的补图上求源点到其他各点的最短路径.

思路:

  补图上求最短路径算是比较经典的题.在这里所求的最短路其实并不需要用到 dijkstra 之类的算法,由于每条边之间的距离都为 1,每条边的权值一样.那么就可以想到这个做法:

  步骤1:根据题意建图.然后建立一个队列,把源点 S 压入队列,其他的各个点存到另一个集合 V 里, 并建立一个数组来存储源点到其他各点的最短距离,初始化为 -1, dis[S] = 0.

  步骤2:从队列首部取出一个节点 v,访问所有与节点 v 不相邻的节点 u,把 u 压入到队列尾部, 并从集合 V 中把 u 除去, 更新dis[u] = dis[v] + 1.

  步骤3:反复重复步骤 2, 直到队列为空.之后 dis 数组里保存的就是答案.

  解决了怎么做之后,还没有完,由于题目给的点数非常大,所以还需要优化下时间.这里比较费时间的就是步骤 2 中的找不相邻的点.这里就可以用 STL 中的 set 来维护集合 V, 也就是未被访问到的点. 初始化 set1 中为所有点(除去源点 S), 当访问的点 v 时, 在 set1 中除去与点 v 相邻的点 u, 并加入到 set2 中,那么 set1 中剩下的点就是所有与点 v 不相邻的点, 依次遍历压入队列. 之后再把 set2 拷贝到 set1, 那么 set1 就是剩下的未被访问到的点,如此反复下去.可以看到,对于每条边只访问一次.每个点也只进一次队列.所以总的时间复杂度为 O(n * m),可以达到要求了.

notes:建立 无向图 的时候每条边要存两次. 所以数组的大小一定是原题所给的边数的两倍! 两倍! 两倍!顺便求一个用链表实现的代码,自己用链表没写出来.(我好菜啊.jpg

代码:

 #include <iostream>
#include <cstdio>
#include <queue>
#include <set>
#include <cstring>
#include <algorithm> using namespace std;
typedef long long LL; const int MAXN = ;
const int MAXE = ;
int n, m, T, S;
int dis[MAXN + ];//保存最终的最短距离 int head[MAXN + ], len; //链式前向星
struct NODE {int to; int next; };
NODE edge[ * MAXE + ]; void addedge(int u, int v) { //链式前向星加边
edge[len].to = v;
edge[len].next = head[u];
head[u] = len++;
} void BFS() { //从起点开始BFS
memset(dis, -, sizeof(dis));
queue <int> Qu;
Qu.push(S); dis[S] = ; //起点初始化
set<int> unsed, hep; //用来维护尚未被访问的点
for(int i = ; i <= n; i++) unsed.insert(i);
unsed.erase(S);
while( !Qu.empty() ) {
int tp = Qu.front(); Qu.pop();
for(int k = head[tp]; k != -; k = edge[k].next) { //从 unsed 中除去和当前拓展节点相邻的点,同时加入到临时辅助的集合中
if(unsed.find(edge[k].to) != unsed.end()) {
unsed.erase(edge[k].to);
hep.insert(edge[k].to);
}
}
for(set<int>::iterator it = unsed.begin(); it != unsed.end(); it++) {// unsed 暂时保存的是和当前拓展节点不相邻的点
Qu.push(*it);
dis[*it] = dis[tp] + ;
}
hep.swap(unsed), hep.clear();//从辅助集合中 copy 剩下的未被访问到的点.
}
} int main() {
scanf("%d", &T);
while(T--) {
memset(head, -, sizeof(head));
scanf("%d%d", &n, &m);
int u, v; len = ;
for(int i = , len = ; i < m; i++) {
scanf("%d%d", &u, &v);
addedge(u, v); addedge(v, u);
}
scanf("%d", &S);
BFS();
for(int i = , j = ; i <= n; i++) if(i != S) printf("%d%c", dis[i], " \n"[++j == n - ]);
}
return ;
}

HDU 5876 Sparse Graph(补图上BFS)的更多相关文章

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

    Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) P ...

  2. HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)

    Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)To ...

  3. HDU 5876 Sparse Graph BFS 最短路

    Sparse Graph Problem Description   In graph theory, the complement of a graph G is a graph H on the ...

  4. HDU 5876 Sparse Graph

    Sparse Graph Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)To ...

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

    http://acm.hdu.edu.cn/showproblem.php?pid=5876 题意: 在补图中求s到其余各个点的最短路. 思路:因为这道题目每条边的距离都是1,所以可以直接用bfs来做 ...

  6. HDU 5876 Sparse Graph BFS+set删点

    Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices s ...

  7. hdu 5876 Sparse Graph icpc大连站网络赛 1009 补图最短路

    BFS+链表 代码改自某博客 #include<stdio.h> #include<iostream> #include<algorithm> #include&l ...

  8. HDU 5867 Sparse Graph (2016年大连网络赛 I bfs+补图)

    题意:给你n个点m条边形成一个无向图,问你求出给定点在此图的补图上到每个点距离的最小值,每条边距离为1 补图:完全图减去原图 完全图:每两个点都相连的图 其实就是一个有技巧的bfs,我们可以看到虽然点 ...

  9. HDU 5876 关于补图的bfs

    1.HDU 5876  Sparse Graph 2.总结:好题,把STL都过了一遍 题意:n个点组成的完全图,删去m条边,求点s到其余n-1个点的最短距离. 思路:把点分为两个集合,A为所有没有到达 ...

随机推荐

  1. Nginx高级应用之Location Url 配置

    原文地址:https://www.linuxidc.com/Linux/2017-03/141910.htm 基本配置 为了探究nginx的url配置规则,当然需要安装nginx.我使用了vagran ...

  2. linux下配置java环境及问题

    一:下载jdk 下载稳定版本http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260.html ...

  3. swiper.js的使用

    点击api文档地址, (1)图片轮播banner <script src="js/jquery-2.1.4.min.js"></script> <sc ...

  4. 数学&搜索:博弈论之极大极小搜索与alpha-beta减枝

    目的是寻找最优的方案使得自己能够利益最大化. 基本思想就是假设自己(A)足够聪明,总是能选择最有利于自己的方案,而对手(B)同样足够聪明,总会选择最不利A的方案 对抗搜索就是对于先手来说,取后手中状态 ...

  5. Eng1—English daily notes

    English daily notes 2015年 4月 Phrases 1. As a side note #作为附注,顺便说句题外话,和by the way意思相近,例句: @1:As a sid ...

  6. XMLHttpRequest 整理

    看了SF 上的一篇文章感触颇深:你真的会使用XMLHttpRequest吗? 在这我写上我读后的笔记: <!DOCTYPE html> <html lang="en&quo ...

  7. spring-boot支持websocket

    spring-boot本身对websocket提供了很好的支持,可以直接原生支持sockjs和stomp协议.百度搜了一些中文文档,虽然也能实现websocket,但是并没有直接使用spring-bo ...

  8. 【洛谷 P2120】 [ZJOI2007]仓库建设(斜率优化)

    题目链接 斜率优化+1,好吧不水分了. 玩具装箱那题以后再做,当作复习吧. \(f[i]=f[j]-(sum[i]-sum[j])*dis[i]+p[i]\) \(f[j]=-dis[i]*sum[j ...

  9. C.Fountains(Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)+线段树+RMQ)

    题目链接:http://codeforces.com/contest/799/problem/C 题目: 题意: 给你n种喷泉的价格和漂亮值,这n种喷泉题目指定用钻石或现金支付(分别用D和C表示),C ...

  10. VMvare 复制的数据库,需要改变的配置

    当我在VMware 上安装了一个linux虚拟机,同时在虚拟机上安装了一系列软件(包括数据库) 我们会修改hostname  ,修改后 对于数据库:我们要把/u01/app/oracle/produc ...