您的位置:首页 > 其它

HDU 5876 Sparse Graph (补图BFS+(链表||set))

2016-09-10 22:32 453 查看
传送门:HDU 5876 Sparse Graph

描述:


Sparse Graph

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Total Submission(s): 311    Accepted Submission(s): 105


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 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.

 

Input

There 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.

 

Output

For 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 Input

1
2 0
1

 

Sample Output

1

 

Source

2016 ACM/ICPC Asia Regional Dalian Online

 

Recommend

wange2014

题意:
求补图的其他的所有点到指定点的最短距离

思路:

补图上的 BFS 是非常经典的问题。一般的做法是用链表(或者偷懒用 std::set)维护还没 BFS 过的点。当要扩展点 u 的时候,遍历一次还没访问过的点 v,如果 uv 没边,那么将 v 入队。否则将 v 留在未扩展点中。

很明显,后者只会发生 m 次,前者只会发生 n 次,所以复杂度是 
O(n
+ m)O(n+m)
.
PS:16年大连区域赛网赛第七题,原题为SCU4444
代码:
#include<bits/stdc++.h>
#define pl(x) cout << #x << "= " << x << endl;
using namespace std;

typedef long long ll;
const int inf=1e9+7;
const int maxn=200100;
int n,m;
ll d[maxn];
bool inq[maxn];
set<int>st,ts;
int head[maxn],ip;
typedef pair<ll,int>P;

void init(){
memset(head,-1,sizeof(head));
memset(inq, false, sizeof (inq));
ip=0;
}

struct note{
int v,w,next;
}edge[maxn<<1];

void addedge(int u,int v,int w){
edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;
}

void Dij(){
priority_queue<P, vector<P>, greater<P> > q;//取最小值
for(int i=1; i<=n; i++)d[i]=inf;
memset(inq, 0, sizeof(inq));
d[1]=0;
q.push(make_pair(0, 1));
while(!q.empty()){
int u,v,w;
P x=q.top();
q.pop();
u=x.second;inq[u]=true;
for(int i=head[u]; i!=-1; i=edge[i].next){
v=edge[i].v;
w=edge[i].w;
if(d[u]+w<d[v]){
d[v]=d[u]+w;
pl(d[v]);
q.push(make_pair(d[v], v));
}
}
}

}

void bfs(int s){
int i,u,v;
st.clear(); ts.clear();
for(i=1;i<=n;i++){
if(i==s)continue;
st.insert(i);//把数放入集合中
}
queue<int>q;
q.push(s);
d[s]=0,d
=inf;
while(!q.empty()){
u=q.front();
q.pop();
for(i=head[u];i!=-1;i=edge[i].next){
v=edge[i].v;
if(st.count(v)==0)continue;//判断当前的数 是否在集合中

st.erase(v);//从当前集合中移除
ts.insert(v);
}
for(set<int>::iterator it=st.begin();it!=st.end();it++){
q.push(*it);
d[*it]=d[u]+1;
}
st.swap(ts); //把两集合内的元素互换
ts.clear(); //当前集合内的元素删去
}
}

int main(){
int t,s;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
int u,v;
init();
for(int i=1; i<=m ;i++){
scanf("%d%d",&u,&v);
addedge(u, v, inf);
addedge(v, u, inf);
}
scanf("%d",&s);
Dij();
bfs(s);
bool flag=false;
for(int i=1; i<=n; i++){
if(i==s)continue;
if(flag)printf(" ");
if(d[i]==inf)printf("-1");
else printf("%d",d[i]);
flag=true;
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: