hdu 5876 Sparse Graph(补图最短路) 2016 ACM/ICPC Asia Regional Dalian Online 1009

来源:互联网 发布:覆雨翻云源码 编辑:程序博客网 时间:2024/04/28 00:44

Sparse Graph

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


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 N1 other vertices.
 

Input
There are multiple test cases. The first line of input is an integer T(1T<35) denoting the number of test cases. For each test case, the first line contains two integers N(2N200000) and M(0M20000). The following M lines each contains two distinct integers u,v(1u,vN)denoting an edge. And S (1SN) is given on the last line.
 

Output
For each of T test cases, print a single line consisting of N1 space separated integers, denoting shortest distances of the remaining N1 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


题意:给一张图,求其补图的某源点的最短路。
由于点很多但是边很少所以不可以对其补图进行操作,建立原图,刚开始时和源点无边的点肯定补图中最短路径是1,并将这些点存入一个集合,下次再判断这这集合的点如果和其他的某个点如果没有一条边相连,这里用队列可以边记录边将集合中的点清空,则该点距离是2,并加入集合。。。接着继续该步骤直到集合空。

#include <queue>#include <vector>#include <cstdio>#include <cstring>using namespace std;const int maxn = 200010;vector<int> ans;queue<int> que;int result[maxn];int flag[maxn];bool vis[maxn];int main(){    int t, n, m, s, step;    scanf("%d", &t);    while (t--)    {        ans.clear();        memset(vis, false, sizeof(vis));        while (!que.empty()) que.pop();        scanf("%d%d", &n, &m);        int x, y;        vector<int> datas[maxn];        for (int i = 0; i < m; ++i)        {            scanf("%d%d", &x, &y);            datas[x].push_back(y);            datas[y].push_back(x);        }        scanf("%d", &s);        que.push(s);        flag[s] = true;        step = 0;        int cnt = 0, tmp;        while(!que.empty())        {            memset(flag, 0, sizeof(flag));            ++step;            tmp = que.front(); que.pop();            cnt = 0;            while(1)            {                cnt++;                for (int i = 0; i < datas[tmp].size(); ++i) flag[datas[tmp][i]]++;                if (!que.empty())                {                    tmp = que.front();                    que.pop();                }                else                {                    break;                }            }            for (int i = 1; i <= n; ++i)            {                if (cnt > flag[i])//表示i点不是和集合里所有点都相连,即补图中可以有一条边相连,在上个距离基础上加1即最短路                {                    if (!vis[i])                    {                        que.push(i);                        vis[i] = true;                        result[i] = step;                    }                }            }        }        for (int i = 1; i <= n; ++i)        {            if (i != s)            {                if (vis[i])                {                    ans.push_back(result[i]);                }                else                    ans.push_back(-1);            }        }        int len = ans.size() - 1;        for (int i = 0; i < len; ++i)            printf("%d ", ans[i]);        printf("%d\n", ans[len]);    }    return 0;}




0 0