zoukankan      html  css  js  c++  java
  • HDU 5876 补图的最短路

    参考博客

    题意:

    给你一个图G,问补图上s到其他n-1个点的最短路。

    题解:

    bfs + set。每次把u点不相连的点入队列,取更新。具体见代码。

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i, a, n) for(int i = a; i <= n; ++ i);
    #define per(i, a, n) for(int i = n; i >= a; -- i);
    typedef long long ll;
    const int N = 2e5+ 5;
    const int mod = 998244353;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    const int G = 3, Gi = 332748118;
    ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    ll lcm(ll a, ll b) { return a * b / gcd(a, b);}
    bool cmp(int a, int b){ return a > b;}
    //
    
    int T, n, m, s;
    int head[N], cnt = 0;
    int dis[N];
    queue<int> q;
    set<int> ta, tb;
    
    
    struct node{
        int to, nxt;
    }edge[N << 1];
    
    void add(int u, int v){
        edge[cnt].to = v, edge[cnt].nxt = head[u], head[u] = cnt ++;
        edge[cnt].to = u, edge[cnt].nxt = head[v], head[v] = cnt ++;
    }
    
    void bfs(){
        while(q.size()) q.pop();
        set<int>::iterator it;
        ta.clear(), tb.clear();
        dis[s] = 0;
        for(int i = 1; i <= n; ++ i) ta.insert(i);
        ta.erase(s);
        q.push(s);
        while(q.size()){
            int u = q.front(); q.pop();
            for(int i = head[u]; i != -1; i = edge[i].nxt){
                int v = edge[i].to;
                if(!ta.count(v)) continue;
                ta.erase(v);
                tb.insert(v);
            }
            for(it = ta.begin(); it != ta.end(); ++ it){
                q.push(*it);
                dis[*it] = dis[u] + 1;
            }
            ta = tb;
            tb.clear();
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T --){
            cnt = 0;
            scanf("%d%d",&n,&m);
            for(int i = 0; i <= n; ++ i) head[i] = -1;
            for(int i = 1; i <= m; ++ i){
                int x, y; scanf("%d%d",&x,&y);
                add(x, y);
            }
            scanf("%d",&s);
            bfs();
            int num = 0;
            for(int i = 1; i <= n; ++ i){
                if(i == s) continue;
                num ++;
                if(dis[i] == INF) printf("-1");
                else printf("%d",dis[i]);
                if(num == n - 1) printf("
    ");
                else printf(" ");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    linux awk命令详解
    世界上最差的系统就是linux,双击不能安装软件
    硬盘安装CentOS 6.0(超级详细图文教程)
    Vim+cscope+ctags+tags阅读源代码
    使用vim看代码:cscope
    解决面板里没有network manager图标的问题
    【b804】双栈排序
    【BZOJ 1002】[FJOI2007]轮状病毒
    【BZOJ 1004】 [HNOI2008]Cards
    【t018】派对
  • 原文地址:https://www.cnblogs.com/A-sc/p/13501509.html
Copyright © 2011-2022 走看看