您的位置:首页 > 其它

HDU 5876 Sparse Graph

2016-09-14 19:23 337 查看
大神的博客:http://blog.csdn.net/dacc123/article/details/52505077 ;

Sparse Graph

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

 

 求图G的补图上s到其他n-1个点的距离,题中有200000个顶点,却只减去最多20000条边,所以补图几乎是一个完全图,(若一个图的每一对不同顶点恰有一条边相连,则称为完全图。完全图是每对顶点之间都恰连有一条边的简单图。n个端点的完全图有n个端点及n(n
− 1) / 2条边),所以bfs不过10次就会扩展完。

在用set/vector保存每条边和顶点,然后进行bfs:

#include <iostream>
#include<set>
#include<algorithm>
#include<stdio.h>
#include<queue>
#include<vector>
#include<string.h>
const int big=2*1e5;
using namespace std;
set<int>g[big+5];
set<int>a;//巧用set可以用set的删除加快搜索
int d[big+5];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m,s;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) a.insert(i),g[i].clear();
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d %d",&x,&y);
g[x].insert(y);
g[y].insert(x);
}
scanf("%d",&s);
a.erase(s);
memset(d,-1,sizeof(d));
d[s]=0;
queue<int>q;
q.push(s);
int de[big+5];
while(!q.empty())
{
int cnt=0;
int v=q.front();
q.pop();
set<int>::const_iterator it;
for(it=a.begin(); it!=a.end(); it++)
{
int i= *it;
if(g[i].find(v)==g[i].end())
{
d[i]=d[v]+1;
q.push(i);
//a.erase(i);//不能在这里删除i,因为删除后的it会过期。
de[cnt++]=i;//所以要记录要删除的i。
}
}
for(int i=0;i<cnt;i++)
a.erase(de[i]);
}
int b=1;
for(int i=1; i<=n; i++)
{
if(i==s) continue;
if(b)
{
b=0;
printf("%d",d[i]);
}
else
{
printf(" %d",d[i]);
}
}
cout<<endl;
}
return 0;
}

后感:要仔细分析题目,如果不知道完全图的话会以为会超时,还有就是要熟悉set,vector容器的用法。付上set用法:http://www.cnblogs.com/BeyondAnyTime/archive/2012/08/13/2636375.html

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: