HDU 5876 Sparse Graph (另类BFS -- 补图的最短路)

23 篇文章 0 订阅

大体题意:

给你一个稀疏图,原图是这个稀疏图的补图,告诉你起始位置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


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

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  N1  other vertices.
 

Input
There are multiple test cases. The first line of input is an integer  T(1T<35)  denoting the number of test cases. For each test case, the first line contains two integers  N(2N200000)  and  M(0M20000) . The following  M  lines each contains two distinct integers  u,v(1u,vN)  denoting an edge. And  S (1SN)  is given on the last line.
 

Output
For each of  T  test cases, print a single line consisting of  N1  space separated integers, denoting shortest distances of the remaining  N1  vertices from  S  (if a vertex cannot be reached from S, output ``-1" (without quotes) instead) in ascending order of vertex number.
 

Sample Input
  
  
1 2 0 1
 

Sample Output
  
  
1
 

Source
 

Recommend
wange2014   |   We have carefully selected several similar problems for you:   5877  5874  5873  5872  5871 
 

Statistic |  Submit |  Discuss |  Note

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值