• 大连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;
    }

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

  • 相关阅读:
    java静态工厂实例
    有道云词典+浏览器开PDF文档=科研者外文阅读福利
    高并发实时性网络视频监控项目实战
    Linux环境下天气预报实现
    2019暑假内容复习
    《分布式与云计算》MOOC第三单元课后测试答案
    安装vivado 2016.1时出错
    N皇后问题的一种解法
    window10下基于anaconda安装tensorflow1.14(cpu版本)
    记一次简单的生产环境Mysql调优
  • 原文地址:https://www.cnblogs.com/huangzzz/p/8666415.html
Copyright © 2020-2023  润新知