HDU5876 Sparse Graph 补图的最短路

来源:互联网 发布:倪妮牛仔裤知乎 编辑:程序博客网 时间:2024/05/28 15:35

题目描述:

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

12 01

Sample Output

1

Source
2016 ACM/ICPC Asia Regional Dalian Online

题目分析:

给一个稀疏图,求这个补图,求这个补图中一个点到其它各点的最短路。
网赛的题解是这么写的:
题解:

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

很明显,后者只会发生 m 次,前者只会发生 n 次,所以复杂度是 O(n + m).

和SCU4444很相似。补图上的BFS。存原图,然后用set保存未被扩展的点,用队列来取出未被扩展的点u,如果与v没有边,v也入队。

代码:

#include<cstdio>#include<cstring>#include<queue>#include<set>#include<algorithm>using namespace std;const int MAXN = 5e5+5;const int INF  = 0x3f3f3f3f;int head[MAXN],e;int dis[MAXN];int ans[MAXN];int n,m;struct Edge{    int v,next;} E[MAXN<<1];void init(){    e=0;    memset(head,-1,sizeof head);}void add(int u,int v){    E[e].v = v;    E[e].next = head[u];    head[u]  = e++;}void BFS(int x){    set<int>ta,tb;    queue<int>Q;    Q.push(x);    dis[x] = 0;    for(int i=1; i<=n; i++) if (i!=x) ta.insert(i);    while(!Q.empty())    {        int u = Q.front();        Q.pop();        for(int i=head[u]; i!=-1; i=E[i].next)        {            int v = E[i].v;            if(!ta.count(v)) continue;            ta.erase(v);            tb.insert(v);        }        for(set<int>::iterator it=ta.begin(); it!=ta.end(); it++)        {            Q.push(*it);            dis[*it] = dis[u] +1;        }        ta.swap(tb);        tb.clear();    }}int main(){    int x;    int u,v;    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        init();        for(int i=0; i<m; i++)        {            scanf("%d%d",&u,&v);            add(u,v);            add(v,u);        }        scanf("%d",&x);        for(int i=1; i<=n; i++) dis[i]=1;        for(int i=head[x]; i!=-1; i=E[i].next) dis[E[i].v]=INF;        BFS(x);        for(int i=1; i<=n; i++)        {            if (i!=x)            {                if (dis[i]==INF) dis[i]=-1;                ans[i]=dis[i];            }        }        for(int i=1; i<=n; i++)        {            if (i!=x)            {                if (i<n) printf("%d ",ans[i]);                else printf("%d",ans[i]);            }        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击