HDU 5876 Sparse Graph 补图求最短路 双set + bfs()

 

                                        Sparse Graph

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2805    Accepted Submission(s): 964


 

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 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,vN) denoting an edge. And S (1≤SN) 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   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 

 

 

#include <bits/stdc++.h>

using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int maxn = 2e5+100;
const int INF = 0x3f3f3f3f;


int T;
int n,m,s;
vector<int> g[maxn];
int d[maxn];

void bfs()
{
  set<int> s1,s2;
  for(int i = 1; i <= n; i++) s1.insert(i);
  memset(d,-1,sizeof(d));
  queue <int> Q;
  Q.push(s);
  d[s] = 0;
  s1.erase(s);
  while(!Q.empty())
  {
    int u = Q.front();Q.pop();
    for(int i = 0; i < g[u].size(); i++)
    {
      int v = g[u][i];
      if(!s1.count(v))  continue;
      s1.erase(v);
      s2.insert(v);
    }
    for(set <int> :: iterator it = s1.begin(); it != s1.end(); it++)
    {
      d[*it] = d[u] + 1;
      Q.push(*it);
    }
    s1.swap(s2);//O(1)
    s2.clear();
  }
}

int main()
{
  scanf("%d",&T);
  while(T--)
  {
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++) g[i].clear();
    for(int i = 0; i < m; i++)
       {
         int u,v;
         scanf("%d%d",&u,&v);
         g[u].push_back(v);
         g[v].push_back(u);
       }
    scanf("%d",&s);
    bfs();
    if(s == n)
     {
       for(int i = 1; i < n-1; i++)
         printf("%d ",d[i]);
        printf("%d\n",d[n-1]);
     }
    else
    {
    for(int i = 1; i < n; i++)
     {
       if(i != s) printf("%d ",d[i]);
     }
    printf("%d\n",d[n]);
   }
 }
 return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值