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)
Total Submission(s): 689 Accepted Submission(s): 238Problem DescriptionIn 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 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.
InputThere are multiple test cases. The first line of input is an integer T(1≤T<35) denoting the number of test cases. For each test case, the first line contains two integers N(2≤N≤200000) and M(0≤M≤20000). The following M lines each contains two distinct integers u,v(1≤u,v≤N) denoting an edge. And S (1≤S≤N) is given on the last line.OutputFor each of T test cases, print a single line consisting of N−1 space separated integers, denoting shortest distances of the remaining N−1 vertices from S (if a vertex cannot be reached from S, output ``-1" (without quotes) instead) in ascending order of vertex number.Sample Input1
2 0
1Sample Output1SourceRecommend
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5876
题目大意:
给你N个点M条无向边的一张图G(2<=N<=200000,0<=M<=20000),并给定起点S,边权均为1,求在这张图的补图H上S到其他N-1个点的最短路,无法到达为-1。
补图:在原图G上X和Y之间有一条边,则补图上X和Y之间没有相连的边,在原图X和Z之间没边,那么在补图上X和Z之间有一条边。
题目思路:
【补图最短路】【宽搜】
比赛的时候数据范围写错了导致队列开小了。WA了。。然而队友神奇的map[5500][5500]居然过了。。不是很懂。。
首先分析一下原图G,如果存在孤立点X(不与任何点相连),那么在补图上这个点X与其他所有的点相连,所以d[X]=1。
对于其余点Y,若Y与S相连则Y的最短路为S->X->Y,d[Y]=2,否则即为S->Y,d[Y]=1。(当N>M+1时必有孤立点)
再考虑没有孤立点的情况,对于原图G,先将S能够到达的点和不能到达的点分为两个集合T和Q,易知Q中所有的点d[i]=1
接着,将Q中的所有点做一次宽搜(最短路SPFA),每个点能够到达的在T中的点d++,Q中所有的点都做完后判断T中的点
对于T中的点X,如果X在原图不能被Q中所有的点走到,那么在补图中一定有一条边从Q中的点Y连向X,则d[X]=d[Y]+1,
如果被Q中所有点走到,那么这个点继续留在X中等待下一次。
做完一次后,继续对新加入Q中的节点做宽搜(最短路SPFA),直到没有新节点加入Q。
如果此时T中还有点则为走不到的,d=-1。
最后输出答案即可。注意多余空格会PE。
注释见代码。
//
//by coolxxx
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdbool.h>
#include<math.h>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define eps (1e-10)
#define J 10000
#define mod 1000000007
#define MAX 0x7f7f7f7f
#define PI 3.14159265358979323
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define N 200004
#define M 20004
using namespace std;
typedef long long LL;
double anss;
LL aans;
int cas,cass;
int n,m,lll,ans;
int S;
int last[N],d[N];
char ch;
int q[M],t[M];
struct xxx
{
int to,next;
}a[M<<];
bool mark[N];
void add(int x,int y)
{
a[++lll].to=y;
a[lll].next=last[x];
last[x]=lll;
}
void work1()
{
int i;
for(i=;i<=n;i++)d[i]=;
for(i=last[S];i;i=a[i].next)d[a[i].to]+=;//孤立点情况与S相连的点答案为2,其余为1
for(i=;i<=n;i++)
{
if(i==n || (i==n- && S==n))ch='\n';
else ch=' ';
if(i==S)continue;
printf("%d%c",d[i],ch);
}
}
void spfa()
{
int i,now,to,l=,r=,x=,y=,sz;
mem(mark,);
for(i=;i<=n;i++)d[i]=mark[i]=;//初始化
q[]=S;mark[S]=;d[S]=;
for(i=last[S];i;i=a[i].next)mark[a[i].to]=;
for(i=;i<=n;i++)//将所有点分成两类
{
if(i==S)continue;
if(mark[i])
q[++r]=i;//与S不相连的,d=1
else
t[++y]=i;//与S相连的,需要进一步判断
}
while(l<r)
{
while(l<r)//将Q中新加入的点now往T集合的点走,每走到一个在T中的点x,d[x]++
{
now=q[++l];
for(i=last[now];i;i=a[i].next)
{
to=a[i].to;
if(mark[to])continue;
d[to]++;
}
}
sz=r;//sz为Q集合的大小,如果在T中的点x在补图中有连向Q的边,那么d[x]<sz(在原图上x不被所有Q中的点走到)
for(i=,x=;i<=y;i++)
{
now=t[i];
if(d[now]==sz)
t[++x]=now;//被所有点走到,继续留在T中
else
{
q[++r]=now;//将这个点加入Q中
d[now]=d[q[l]]+;//这个点的距离为上一个距离+1
mark[now]=;//标记为在Q中
}
}
y=x;//T的新大小
}
for(i=;i<=y;i++)d[t[i]]=-;//若Q中的点都遍历完,T中还有剩余的点,则为走不到的点,d=-1
for(i=;i<=n;i++)
{
if(i==n || (i==n- && S==n))ch='\n';
else ch=' ';
if(i==S)continue;
printf("%d%c",d[i],ch);
}
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k;
int x,y,z;
// init();
for(scanf("%d",&cass);cass;cass--)
// for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
// while(~scanf("%s",s))
// while(~scanf("%d",&n))
{
lll=cas=;mem(last,);mem(mark,);
scanf("%d%d",&n,&m);
for(i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
if(!mark[x])mark[x]=,cas++;
if(!mark[y])mark[y]=,cas++;
}
scanf("%d",&S);
if(cas<n)work1();//孤立点情况
else spfa();//无孤立点情况
}
return ;
}
/*
// //
*/
HDU 5876 Sparse Graph 【补图最短路 BFS】(2016 ACM/ICPC Asia Regional Dalian Online)的更多相关文章
- HDU 5874 Friends and Enemies 【构造】 (2016 ACM/ICPC Asia Regional Dalian Online)
Friends and Enemies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 5875 Function 【倍增】 (2016 ACM/ICPC Asia Regional Dalian Online)
Function Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- HDU 5873 Football Games 【模拟】 (2016 ACM/ICPC Asia Regional Dalian Online)
Football Games Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hud 5876 2016 ACM/ICPC Asia Regional Dalian Online
题意:给一个图 给定一个点s 求补图中s点到达各个点的最短路 思路:从s点开始bfs 在图中与s点有连接的都是在补图中不能直接到达的点 反之在补图中都是可以直接到达的点 由此bfs ((( 诡异的写法 ...
- hdu 5877 线段树(2016 ACM/ICPC Asia Regional Dalian Online)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- 2016 ACM/ICPC Asia Regional Dalian Online HDU 5877 Weak Pair treap + dfs序
Weak Pair Problem Description You are given a rooted tree of N nodes, labeled from 1 to N. To the ...
- 2016 ACM/ICPC Asia Regional Dalian Online 1002/HDU 5869
Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K ( ...
- 2016 ACM/ICPC Asia Regional Dalian Online 1006 /HDU 5873
Football Games Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 5868 2016 ACM/ICPC Asia Regional Dalian Online 1001 (burnside引理 polya定理)
Different Circle Permutation Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K ...
随机推荐
- URAL 2032 - Conspiracy Theory and Rebranding【本源勾股数组】
[题意] 给出三角形的三个边长,均是10^7以内的整数,问三角形的三个角的坐标是否能均是整数,输出其中任意一个解. [题解] 一开始想的是枚举一条边的横坐标,然后通过勾股定理以及算角度求出其他点的坐标 ...
- 2进制,16进制,BCD,ascii,序列化对象相互转换
public final static char[] BToA = "0123456789abcdef".toCharArray() ; 1.16进制字符串转为字节数组 /** * ...
- 判断浏览器是否支持FileReader
1.js代码: //判断浏览器是否支持FileReader if (typeof FileReader == "undefined") { document.write(" ...
- MVC+EF 的增删改查操作
1. //创建EF映射对象数据集 static Models.db_JiaoYouEntities DbDeleteData = new Models.db_JiaoYouEntities(); 2. ...
- C# Activator.CreateInstance()
C#在类工厂中动态创建类的实例,所使用的方法为: 1. Activator.CreateInstance (Type) 2. Activator.CreateInstance (Type, Objec ...
- c++ Cout 输出格式
控制符是在头文件iomanip.h中定义的对象.使用前必须把iomanip.h包含进来 1. I/O的书写格式 I/0流是输入或输出的一系列字节,当程序需要在屏幕上显示输出时,可以使用插入操作符“&l ...
- Nagios新添加的hosts和services有时显示,有时不显示问题解决
在nagios配置文件hosts.cfg和services.cfg中添加了新服务器和服务列表,重启nagios服务后刷新监控页面,新添加的服务器和服务列表有时能显示出来,有时又显示不出来. 解决方法: ...
- TOM大师脚本-show space 多个版本,谢谢大牛们
示例一 该脚本需区分 对象的管理方式是 自动还是 手动, 对手动管理方式 的表显示很全面 SQL> exec show_space_old('MAN_TAB','DEV','TABLE'); F ...
- 浅析CSS中的haslayout
作为一名web开发人员,最大的希望不是自己的水平有多高,而是希望浏览器厂家能够统一标准,相信任何一个只要是接触过web程序开发的人员都有那样的感受,就是浏览器之间的兼容性问题总是让我们的工作平添诸多的 ...
- Javascript参数传递中值和引用的一种理解
值(value)和引用(reference)是各种编程语言老生常谈的话题,js也不例外. 我将剖析一个例子的实际运行过程,跟大家分享我对js参数传递中的值和引用的理解. 参考官网数据类型的两种分类,本 ...