链接:http://acm.hdu.edu.cn/showproblem.php?pid=5876
题意:求给定图的补图的单源最短路
题解:在原图上判断两点间可达性进行bfs,已经遍历过的点直接删掉
CODE:
#include <bits/stdc++.h>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug"<<endl
const int MAXN = 200007;
const int MAXM = 20007;
const int MOD = 1e9 + 9;
using namespace std;
struct node
{
int v,next;
} edge[MAXN<<1];
int ind,head[MAXN<<1];
void add_edge(int u, int v)
{
edge[ind].v=v;
edge[ind].next=head[u];
head[u]=ind++;
}
int dis[MAXN];
set<int> a,b;
set<int>::iterator it;
int T,n,m,s;
void solve(int start)
{
a.clear(),b.clear();
memset(dis,-1,sizeof(dis));
dis[start]=0;
for(int i=1; i<=n; ++i)
if(i!=s)
a.insert(i);
queue<int> q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(a.count(v))
{
a.erase(v);
b.insert(v);
}
}
for(it=a.begin(); it!=a.end(); it++)
{
dis[*it]=dis[u]+1;
q.push(*it);
}
a.swap(b);
b.clear();
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
ind=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
int u,v;
for(int i=0; i<m; ++i)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
scanf("%d",&s);
solve(s);
int cnt=0;
for(int i=1; i<=n; ++i)
{
if(i!=s)
{
if(cnt)printf(" ");
printf("%d",dis[i]);
cnt++;
}
}
printf("\n");
}
return 0;
}
/*
1
2 0
1
*/