HDU 5876 最短路+补图

来源:互联网 发布:python str empty 编辑:程序博客网 时间:2024/06/06 16:35

题目

Sparse Graph

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


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


题意


  输入的是一个图,但是我们要求的是补图,补图就是整个图减去我们输入的图,这里是百度百科 https://baike.baidu.com/item/%E8%A1%A5%E5%9B%BE?fr=aladdin。


 我先知道了一个点S,求的就是S在这个补图中,到其他个点的最短路,如果不存在就输出-1


解题思路


这个题的关键在于怎么去处理补图,求最短路对我们来说不是什么大问题,那怎么处理补图呢,我们开一个数组link,里面存当前点可以到达的点,再开一个数组inlink存当前点不能到达的点,初始化link的时候把除了自己本身的点我们都加上,无法到达的我们先一个也不存,然后假设我们在起点S,那么根据输入,我们就能找到S无法到达的点,我们把该点从link里面删除,把他加入到inlink,这样子我们计算最短路,只要找link数组就好了,而且这些点到S就是d[s]+1,这里有一个巧妙的计算就是,因为我们是从起点S开始的,如果我们已经找到这个点了我们就不需要再找一次(也就是再加入一次link数组)了,因为他已经是最短路了,需要加入link数组的只有我们还没有找到的点,而我们还没找到的点都在inlink里面,处理完之后交换一下就好了,具体的看代码吧

代码里面用的Set,因为方便插入和删除而且是唯一的,就像图中的点一样每个点也是唯一的。

#include<set>#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=200000+6;int n,m;int d[maxn];vector<int>e[maxn];void dfs(int s){    memset(d,0,sizeof(d));    set<int>link,inlink;    for(int i=1;i<=n;i++)    {        if(i!=s)            link.insert(i);    }    queue<int> q ;    q.push(s);    while(!q.empty())    {        int x=q.front();        q.pop();        for(auto &y:e[x])        {            if(!link.count(y))                continue;            link.erase(y);            inlink.insert(y);        }        for(auto &y:link)        {            d[y]=d[x]+1;            q.push(y);        }        link.swap(inlink);        inlink.clear();    }    int flag=0;    for(int i=1;i<=n;i++)    {        if(i!=s)        {            if(flag)            {                printf(" ");            }            if(!d[i])                printf("-1");            else                printf("%d",d[i]);            flag=1;        }    }    printf("\n");}void work(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        e[i].clear();    int u,v;    for(int i=0;i<m;i++)    {        scanf("%d%d",&u,&v);        e[u].push_back(v);        e[v].push_back(u);    }    int s;    scanf("%d",&s);    dfs(s);}int main(){    int T;    scanf("%d",&T);    while(T--)    {        work();    }    return 0;}


原创粉丝点击