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 ...
随机推荐
- 动态拼接 sql的时候 里面 如果有变量的话 按上面的方式进行处理
set @Sql_Sql = N' select top 1 @m_zw=zw,@m_zh=temp from ket where zd=''ddd'' ' print @Sql_Sql EXEC s ...
- hadoop集群环境搭建准备工作
一定要注意hadoop和linux系统的位数一定要相同,就是说如果hadoop是32位的,linux系统也一定要安装32位的. 准备工作: 1 首先在VMware中建立6台虚拟机(配置默认即可).这是 ...
- NP-难题
所谓NP-难题,在给定的一个信息系统中,假设研究对象书目为m,属性书目为n,则要考察的属性集P的一个子集是否为最小子集,要进行n*m*m次的比较.而n个属性可构成2的n次方个子集,这些子集都有可能是最 ...
- Oracle 左连接、右连接、全外连接、(+)号作用、inner join(等值连接) (转载)
Oracle 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 外连接(Outer Join) oute ...
- 【转】 UITableViewCell的标记、移动、删除、插入
原文: http://blog.csdn.net/duxinfeng2010/article/details/7725897 这篇文章是建立在 代码实现 UITableView与UITableView ...
- CI 框架增加公用函数-如何使用Helper辅助函数
在CI框架增加一个公用的函数,或者说是要在页面上调用一个函数,可以写一个帮助类如:menu_helper.php.类名必有_helper后缀名,这标识为帮助类.文件要放在application/hel ...
- C++中的static关键字的总结 (转载)
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...
- SGU 156. Strange Graph(欧拉路)
时间限制:0.25s 空间限制:6M 题目描述 让我们想象一个无向图G=<V,E>.如果边(u,v)在边集E中,那么我们就说两个顶点u和v是邻接点.在这种情况下,我们也说u是v的一个邻接点 ...
- newInstance()和new的区别
在初始化一个类,生成一个实例的时候:newInstance() 和 new 有什么区别?用newInstance与用new是有区别的,区别在于创建对象的方式不一样,前者是使用类加载机制,那么为什么会有 ...
- QQ弹窗代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...