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 ...
随机推荐
- 惠普 hpssacli 工具使用
查看raid卡信息(包括控制器状态.Cache状态.电池状态) # hpssacli ctrl all show status 查看raid详细信息 # hpssacli ctrl slot=0 sh ...
- python----------进程、线程、协程
进程与线程 什么是进程(process)? An executing instance of a program is called a process. Each process provides ...
- day-10
/* 还是习惯在插入里面写东西 233 今晚停电了 一屋人唱歌讲鬼故事 挺开心的 还有不到十天大家就要分开了 还记得第一次来机房的时候 大家都还不认识 到现在快一年了 大家可以一起闹一起笑 一起没心没 ...
- react初识
如下是在研究中记录的笔记: 1,作用:局部的更新dom结构;虚拟dom保证性能2,和mvc不同,mvc是对于技术上的分离(分类),而react是组件上的分离,每个视图模块分离,复用,以视图模块为单位3 ...
- oracle中用comment on的用法
oracle中用comment on命令给表或字段加以说明,语法如下:COMMENT ON { TABLE [ schema. ] { table | view } | COLUMN [ s ...
- godaddy_关于产品退款
You're chatting with Danny.Danny - Thank you for contacting live chat. My name is Danny. How can I a ...
- winows8.1或winows7 64bit 安装Itunes 64bit 11.1.3 无法打开一直停止工作的解决办法
winows8.1或winows7 64bit 安装Itunes 64bit 11.1.3 无法打开一直停止工作的解决办法 系统环境变量里的Path追加 ;C:\program files (x86) ...
- iOS打包ipa安装包的流程
应用的发布也分两种 一种是.打包成ipa上传到国内第3方软件市场,当用户的手机已经JailBreak时,双击下载的ipa文件就可以安装软件 (ipa同android的apk包一样,实质是一个压缩包) ...
- HDOJ 2037简单的贪心算法
代码: #include<iostream> using namespace std; int main() { int n,s,t1[100],t2[100],i,t,j; while( ...
- Bootstrap_Javascript_固定定位
Affix 插件可以对任何元素进行固定定位,其中比较简单的方法,就是通过自定义属性 data 来触发.其主要包括两个参数: 1.data-spy:取值 affix,表示元素固定不变的. 2.data- ...