HDU 5876 Sparse Graph(补图的最短路)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/readlnh/article/details/52805931

题意

给出一个图,和一个起点,求在该图的补图中从起点到其他N-1个点的最短距离。如果不连通输出-1.

思路

用set将未走过的点放置进去,并在对点的邻边进行扩展的时候,把能走到的邻点删除掉(即补图中可以走到的邻点保留)

代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <set>
using namespace std;

const int kMaxn = 200000 + 10;
const int kMaxm = 20000 + 10;

struct Edge {
  int from,to;
  int next;
}g[kMaxm * 2];

int head[kMaxn];
int dis[kMaxn];

int top;
int n,m,s;

void Init() {
  top = 0;
  memset(head, -1, sizeof(head));
  memset(dis, -1, sizeof(dis));
}

void AddEdge(int from, int to) {
  g[top].from = from;
  g[top].to = to;
  g[top].next = head[from];
  head[from] = top++;
}

void Bfs() {
  queue<int>que;
  que.push(s);
  dis[s] = 0;
  set<int>s1,s2;
  for(int i = 1; i <= n; i++) 
    if(i != s) s1.insert(i);
  while(!que.empty()) {
    int u = que.front(); que.pop();
    for(int i = head[u]; i != -1; i = g[i].next) {
      int v = g[i].to;
      if(!s1.count(v)) continue;
       s1.erase(v);
       s2.insert(v);
    }
    for(set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
      int v = *it;
      que.push(v);
      dis[v] = dis[u] + 1;  
    }
    s1.swap(s2);
    s2.clear();
  }
}

int main() {
  int t;
  scanf("%d", &t);
  while(t--) {
    Init();
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++) {
      int u,v;
      scanf("%d %d", &u, &v);
      AddEdge(u, v);
      AddEdge(v, u);
    }
    scanf("%d", &s);
    Bfs();
    for(int i = 1; i < n; i++) 
      if(i != s) 
        printf("%d ", dis[i]);
    if(n != s)
      printf("%d\n", dis[n]);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/readlnh/article/details/52805931
今日推荐