hdu5876
题目
给你一个图,一个起点,求这个图的补图的单源最短路。
思路
http://blog.csdn.net/timelimite/article/details/52498284
两个set就是为了实现“未扩展的点想用它但是和它相连了所以不能用”的情况。
代码
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn = 201000;
vector<int> g[maxn];
int n,m,s;
int dis[maxn];
void solve()
{
set<int> a,b;
set<int>::iterator it;
memset(dis,0,sizeof(dis));
queue<int> q;
q.push(s);
for(int i=1; i<=n; i++)
if(i!=s) a.insert(i);
while(!q.empty())
{
int now=q.front();
q.pop();
for(unsigned int i=0; i<g[now].size(); i++)
{
int v=g[now][i];
if(!a.count(v))
continue;
b.insert(v);
a.erase(v);
}
for(it=a.begin(); it!=a.end(); it++)
{
dis[*it]=dis[now]+1;
q.push(*it);
}
a.swap(b);
b.clear();
}
int flag=0;
for (int i = 1; i <= n; i ++)
{
if (i != s)
{
if (flag)
printf(" ");
if (!dis[i])
printf("-1");
else
printf("%d",dis[i]);
flag = 1;
}
}
printf("\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1; i<=n; i++) g[i].clear();
for(int i=0; i<m; i++)
{
int u,v;
scanf("%d %d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
scanf("%d",&s);
solve();
}
return 0;
}