图论 补图最短路->bfs+set

来源:互联网 发布:windows dock软件 编辑:程序博客网 时间:2024/05/18 16:37

hdu5877

题意:T组样例,没组n个点,m条边, 再输入一个点k,k<n,求k到补图中各点的最短路。

题解:用set 去存不相邻的点,然后累计增加长度,


#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#include <set>#include <queue>using namespace std;const int INF=0x7f7f7f;const int maxn=200005;struct Edge{int to,from;}edge[maxn];int head[maxn],top;int n,m;int dis[maxn];int into(){memset(head,-1,sizeof(head));memset(dis,INF,sizeof(dis));top=0;}void add(int u,int v){edge[top].to=u;edge[top].from=head[v];head[v]=top++;}int bfs(int st){set<int> s1;set<int> s2;set<int>::iterator it;//除了st 计算的这个点其他都收到s1 集合里 for(int i=1;i<=n;i++)if(i!=st)s1.insert(i);queue<int>q;q.push(st);dis[st]=0;//只能在st的基础上加 while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].from){int to=edge[i].to;//s1集合里没有就跳过 if(!s1.count(to))continue;//s1集合里有,把这个点放到 s2里面//s1集合里有,说明点u和这些点相邻// 但是我们要计算不相邻的,所以拿出来单独考虑 s1.erase(to);s2.insert(to);}//s1中现在存的是 和u点不相邻的数//s2中现在存的是和u相邻的数 for(it=s1.begin();it!=s1.end();it++){q.push(*it);//点到u的距离+1 dis[*it]=dis[u]+1;}//换回去,再次比较 s1.swap(s2);s2.clear();}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);into();for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);add(u,v);add(v,u);}int stt;scanf("%d",&stt);bfs(stt);//输出结果 for(int i=1;i<=n;i++){if(i==stt)continue;//i没走过 if(dis[i]==INF)printf("-1");else printf("%d",dis[i]);if(i==n)printf("\n");else printf(" ");}}return 0;}


0 0
原创粉丝点击