zoukankan      html  css  js  c++  java
  • 大连acm hdu 5876 补图

    题目:http://hdu.hustoj.com/showproblem.php?pid=5876 

     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
    1 2 0 1
     


    Sample Output
    1
     


    Source
     
     
     
     
    题意:  给你1样例
                给你n个点和m条边
                输入m条边后
                输入起点s
     
          求原图的补图中,,起点s到各个点的最短距离并输出   
         补图 ;   一个n个点的图有n*(n-1)*0.5条边,,,除去原图上的边剩下的所有边组成补图
      
    概念如图 ;
      
                                                                
     
     
    好了题意清楚了,,其实刚开始想法很简单,,不就是补图嘛,,通过原来的图把补图还原出来,直接迪杰就ok
     
    但是复杂度过高,优化是不可能的,,所以又找到了一种做法  因为只会出现3种答案吧(-1,,1,,2)
     
    从起点找起,,把和起点没有联系的点用队列存起来,如图就是存4和5    更新dis[4]和dis[5]=1     从队列中取出4和5 分别为起点  找没有联系的点3和2   更新队列和dis[3],,dis[2]=dis[4]+1;
     
    好了方法已经找到了,,写出来了也,,但是还是超时 ,,想半天原来红色区域的查找复杂度也有n*(n-x)*(n-x)....显然超时
     
    怎么办呢,,想到了set维护,,set能跟快速的管理和查找删除 所需要的元素  所以代码就出来了  因为对于set的维护还不熟悉只能看别人的代码,,实力太弱
     
    对着网上写的代码:后面会补上自己的代码
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<algorithm>
    #include<map>
    #define maxn 200005
    using namespace std;
    int n,m,s;
    int x,y;
    set<int>book;//存所有没扩展到的点
    set<int>mp[maxn]; //存原图
    int ans[maxn];    // 最短距离
    void bfs(int s)
    {
        ans[s]=0;
        queue<int>que;
        que.push(s);   //把起点存入队列
        for(int i=1;i<=n;i++)
        {
            if(i!=s)book.insert(i);  //所有点先存入
        }
        set<int>del;  //存要删除的已访问的点
        while(!que.empty())
        {
            int now=que.front();
            que.pop();
            set<int>::iterator it;
            del.clear();  //清空所有元素
            for(it=book.begin();it!=book.end();it++)    //查找与now没有连接的点 可以说是这题的难点所在
            {
                if(!mp[now].count(*it))  //返回mp[now]的元素个数
                {
                    if(ans[*it]==-1)
                    {
                        ans[*it]=ans[now]+1;
                        del.insert(*it);
                        que.push(*it);
                    }
                }
            }
            for(it=del.begin();it!=del.end();it++)
            {
                book.erase(*it);  //删除book里的已经访问元素
            }
        }
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            memset(ans,-1,sizeof(ans));  //初始化ans数组
            for(int i=0;i<=n;i++)
            {
                mp[i].clear();   //清空mp
            }
            book.clear(); //清空book
            for(int i=0;i<m;i++)
            {
                cin>>x>>y;
                mp[x].insert(y);
                mp[y].insert(x);   //双向存点
            }
            cin>>s;
            bfs(s);
            //  以下是输出格式
            for(int i=1;i<=n;i++)
            {
                if(s==i)continue;
                cout<<ans[i];
                if(s==n)
                {
                    if(i!=n-1)printf(" ");
                    else cout<<endl;
                }
                else
                {
                    if(i!=n)cout<<" ";
                    else cout<<endl;
                }
            }
        }
        return 0;
    }

    思路并不复杂,,就是想要维护操作的时候想不到

  • 相关阅读:
    Docker容器启动时初始化Mysql数据库
    使用Buildpacks高效构建Docker镜像
    Mybatis 强大的结果集映射器resultMap
    Java 集合排序策略接口 Comparator
    Spring MVC 函数式编程进阶
    换一种方式编写 Spring MVC 接口
    【asp.net core 系列】6 实战之 一个项目的完整结构
    【asp.net core 系列】5 布局页和静态资源
    【asp.net core 系列】4. 更高更强的路由
    【Java Spring Cloud 实战之路】- 使用Nacos和网关中心的创建
  • 原文地址:https://www.cnblogs.com/huangzzz/p/8666415.html
Copyright © 2011-2022 走看看