大体题意:
给你一个稀疏图,原图是这个稀疏图的补图,告诉你起始位置S,求从原图S位置出发,求从S到每个位置的最短路!(路的权值都是1),如果到不了的输出-1!
思路:
很强的一个题,自己一点思路都没有,用dijkstra 想了许久,赛后补得!
这是一个求补图的最短路问题,看了许多学长的博客!都认为这是一个经典问题,,看来还差的远啊!
用BFS,思路比较巧妙!
首先是建图,建图肯定不能建立补图,既会超时又会爆内存!
就是建立原图,用链表的形式的建立,不管你怎么实现了,最后的形式 就是 可以从1个点 一直走到与它相连的或间接相连的最后一个位置!
举个例子,假如有个图是这样1-4-6-3-5
那么1的next 是4 4的next 是6 6 的next 是3 3 的next 是5 反向也可以!head[i]为i 节点的头!
有了这些准备工作,我们就可以BFS了!
需要两个set <int> ta.tb 和一个队列 queue<int>q
ta中的元素表示未访问的节点,tb 中肯定就是访问过的了,(但也不是全部,因为一部分会从中删掉了(删掉肯定也是访问了!))
说说这个大体过程!
初始化时,是先把 从1~n 除了S全部insert 到ta里,然后枚举S的一长串路(不断的next),这些直接或间接与S相连的点,肯定不能一部到达了!所以把他们放到 tb里,从ta删除!那么ta 中剩下的都是可以一部到达了,更新这些点的距离 也就是dis ++ 并把他们压入队列(这些点也肯定是要在扩展的嘛!)
然后tb 中就是没访问了! 在把他们放到ta 里 清空tb!
说白了 就是ta 处理,tb 只是个临时的set!
或许说的还不明白,在仔细想想吧! 很巧妙!
领悟见代码: = = !
#include<cstdio>
#include<set>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 20000 + 10;
int head[maxn*10];
int n, m, dis[maxn*10], s;
set<int>ta,tb;
set<int>::iterator it;
struct Node{
int v;
int next;
}p[maxn << 1];
queue<int>q;
int cnt = 0;
void addEdge(int u,int v){
p[cnt].v = v;
p[cnt].next = head[u];
head[u] = cnt++;
}
void bfs(){
ta.clear();
tb.clear();
while(!q.empty())q.pop();
q.push(s);
dis[s] = 0;
for (int i = 1; i <= n; ++i){
if (i != s)ta.insert(i);
}
while(!q.empty()){
int u = q.front();
q.pop();
for (int i = head[u]; i != -1; i = p[i].next){
int t = p[i].v;
if (!ta.count(t))continue;
ta.erase(t);
tb.insert(t);
}
for (it = ta.begin(); it != ta.end(); ++it){
q.push(*it);
dis[*it] = dis[u] + 1;
}
ta = tb;
tb.clear();
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
cnt = 0;
memset(head,-1,sizeof head);
scanf("%d %d",&n,&m);
for (int i = 0; i < m; ++i){
int u,v;
scanf("%d %d", &u, &v);
addEdge(u,v);
addEdge(v,u);
}
scanf("%d",&s);
memset(dis,inf,sizeof dis);
bfs();
int cnt2 = 0;
for (int i = 1; i <= n; ++i){
if (i == s)continue;
if (cnt2++)printf(" ");
if (dis[i] == inf)printf("-1");
else printf("%d",dis[i]);
}
puts("");
}
return 0;
}
Sparse Graph
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1528 Accepted Submission(s): 543
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.
1 2 0 1
1