hdu 5876 (补图BFS) Sparse Graph

Posted 鲨鱼辣椒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5876 (补图BFS) Sparse Graph相关的知识,希望对你有一定的参考价值。

题目:这里

题意:

相当于一开始给一个初始好了的无向完全图给你,然后给让你删除m条边,再给你一个点v,最后问你在剩下的图里从这个点v出发能到达所有边点的最小路径是多少?

一看是所有点的最小路径,一看就觉得是个bfs,记忆化搜一下然后加个优化什么的,由于数据不知道是个什么奇葩而且比赛中还改数据,所以很多人wa的莫名其妙,

过也过的莫名其妙,我虽然过了但觉得有点不靠谱,赛后看了https://async.icpc-camp.org/d/546-2016的题解思路写了一发,总感觉更靠谱一点。

 

之前自己过的,就是用set记录那删掉的m条边,dis[i]数组记录每个结点的最小路径,当所有的点都搜到过的时候就可以结束了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<set>
 6 #include<queue>
 7 using namespace std;
 8 
 9 const int M = 2e5 + 10;
10 set<int>s[M];
11 int n;bool vis[M];
12 int dis[M],ans;
13 
14 int min(int x,int y){return x<y?x:y;}
15 
16 struct node{
17    int po,dis;
18 };
19 
20 void bfs(int pos)
21 {
22     memset(vis,false,sizeof(vis));
23     queue<node>p;
24     node now,next;
25     now.po=pos;now.dis=0;
26     p.push(now);
27     vis[pos]=true;
28     while (!p.empty()){
29         now=p.front();
30         p.pop();
31         for (int i=1 ; i<=n ; i++){
32             next.po=i;next.dis=now.dis+1;
33             if (next.po==now.po) continue;
34             if (vis[next.po]) continue;
35             bool flag=false;
36             if (s[now.po].find(next.po)!=s[now.po].end())
37                 flag=true;
38             if (flag) continue;
39             vis[next.po]=true;
40             dis[next.po]=min(next.dis,dis[next.po]);
41             p.push(next);ans++;
42         }
43         if (ans==n) return ;
44     }
45 }
46 
47 
48 
49 int main()
50 {
51     int t;
52     scanf("%d",&t);
53     while (t--){
54         int m;
55         scanf("%d%d",&n,&m);
56         for (int i=1 ; i<=n ; i++) s[i].clear(),dis[i]=M;
57         while (m--){
58             int u,v;
59             scanf("%d%d",&u,&v);
60             s[u].insert(v);
61             s[v].insert(u);
62         }
63         int pos;
64         scanf("%d",&pos);
65         ans=1;
66         bfs(pos);
67          if (n!=pos){
68         for (int i=1 ; i<=n ; i++){
69             if (i==pos) continue;
70             if (i!=n) printf("%d ",dis[i]);
71             else printf("%d\n",dis[i]);
72         }
73         }
74         else{
75             for (int i=1 ; i<n ; i++){
76                 if (i!=n-1) printf("%d ",dis[i]);
77                 else printf("%d\n",dis[i]);
78             }
79         }
80     }
81     return 0;
82 }

 

后来看了别人的思路自己写的

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;

const int M = 2e5 + 10;

int n,di[M],head[M],cas;

struct Edge{
    int to,next;
}edge[M*2];

void add(int u,int v)
{
    edge[++cas].next=head[u];
    edge[cas].to=v;
    head[u]=cas;
}

int min(int x,int y){return x<y?x:y;}

struct node{
   int po,dis;
};

void bfs(int pos)
{
    set<int>s,e;
    set<int>::iterator it;
    for (int i=1 ; i<=n ; i++) s.insert(i),di[i]=M;
    queue<node>p;
    s.erase(pos);
    node now,next;
    now.po=pos;now.dis=0;
    p.push(now);
    while (!p.empty()){
        now=p.front();
        p.pop();
        for (int i=head[now.po] ; i ; i=edge[i].next){
            int v=edge[i].to;
            if (s.find(v)==s.end()) continue;
            s.erase(v);
            e.insert(v);
        }
        for (it=s.begin() ; it!=s.end() ; it++){
            next.po=*it;next.dis=now.dis+1;
            di[next.po]=min(next.dis,di[next.po]);
            p.push(next);
        }
        s.swap(e);e.clear();
    }
}



int main()
{
    int t;
    scanf("%d",&t);
    while (t--){
        int m;cas=0;
        scanf("%d%d",&n,&m);
        memset(head,0,sizeof(head));
        while (m--){
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        int pos;
        scanf("%d",&pos);
        bfs(pos);
        if (n!=pos){
        for (int i=1 ; i<=n ; i++){
            if (i==pos) continue;
            if (i!=n) printf("%d ",di[i]);
            else printf("%d\n",di[i]);
        }
        }
        else{
            for (int i=1 ; i<n ; i++){
                if (i!=n-1) printf("%d ",di[i]);
                else printf("%d\n",di[i]);
            }
        }
    }
    return 0;
}

 

以上是关于hdu 5876 (补图BFS) Sparse Graph的主要内容,如果未能解决你的问题,请参考以下文章

HDU - 5876 :Sparse Graph (完全图的补图的最短路 -BFS&set)

Sparse Graph---hdu5876(set+bfs)

[HDOJ5876]Sparse Graph(补图最短路)

HDU 5876:Sparse Graph(BFS)

hdu5876 Sparse Graph(补图最短路)

HDU 5876 Sparse Graph BFS 最短路