2019nc#6

https://ac.nowcoder.com/acm/contest/886#question

题号标题已通过代码题解/讨论通过率团队的状态
A Garbage Classification 点击查看 进入讨论 972/1543  通过
B Shorten IPv6 Address 点击查看 进入讨论 541/4388  通过
C Palindrome Mouse 点击查看 PAM 43/206 yzj补了
D Move 点击查看 进入讨论 465/3911  通过
E Androgynos 点击查看 进入讨论 116/532  通过
F K-ary Heap 点击查看 进入讨论 8/34 未通过
G Is Today Friday? 点击查看 蔡勒公式,去重暴力 71/779  👌
H Train Driver 点击查看 进入讨论 5/26  
I Can They Go to Galar? 点击查看 进入讨论 3/23 未通过
J Upgrading Technology 点击查看 进入讨论 554/3837  通过

 H Train Driver

题意

 有一个边权都为1的无向图,有三个人,A只会出现在sa集合的点中,B只会出现在sb集合点中。C可以等概率出现在任意点。

问三个人走到同一个点的总路程的期望。

思路

每个点在固定sa,sb的情况下,dd[i] = dis[sa][i] + dis[sb][i]。

然后就是用dd[i]取更新其他点。

需要利用桶排序的思想,还要运用两个队列去优化

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include <bits/stdc++.h>

using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;



template<typename T>
inline T read(T&x){
    x=0;int f=0;char ch=getchar();
    while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
    while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x=f?-x:x;
}

const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;

/**********showtime************/
            const int maxn = 1e5+9;
            vector<int>sa, sb;
            vector<int>mp[maxn];
            ll gcd(ll a, ll b) {
                if(b == 0) return a;
                return gcd(b, a % b);
            }

            ll sum = 0;
            int dis[2][22][maxn];
            int n,m;
            void bfs(int s, int id, int flag){
                queue<int>que;
                dis[flag][id][s] = 0;
                que.push(s);
                while(!que.empty()) {
                    int u = que.front();    que.pop();
                    for(int v : mp[u]) {
                        if(dis[flag][id][v] > dis[flag][id][u] + 1) {
                            dis[flag][id][v] = dis[flag][id][u] + 1;
                            que.push(v);
                        }
                    }
                }
            }
            int dd[maxn];
            void dji() {
                priority_queue <pii> que;
                for(int i=1; i <=n; i++) que.push(pii(-dd[i], i));
                while(!que.empty()) {
                    pii t = que.top(); que.pop();
                    int u = t.se, f = -1*t.fi;
                    if(dd[u] < f) continue;
                    for(int v : mp[u]) {
                        if(dd[v] > dd[u] + 1) {
                            dd[v] = dd[u] + 1;
                            que.push(pii(-dd[v], v));
                        }
                    }
                }
            }
            queue<pii>que1,que2;
            queue<int>lev[maxn * 2];
            void solve(int s1, int s2) {
//                cout<<s1<<" ,, " << s2<<endl;
                int mx = 0;
                for(int i=1; i<=n; i++) {
                    dd[i] = dis[0][s1][i] + dis[1][s2][i];
                    lev[dd[i]].push(i);
                    mx = max(mx, dd[i]);
                }
                for(int i=0; i <= mx; i++) {
                    while(!lev[i].empty()) {
                        int u = lev[i].front(); lev[i].pop();
                        que1.push(pii(i, u));
                    }
                }
                while(!que1.empty() || !que2.empty()) {
                    pii t1 = pii(inf, inf), t2 = pii(inf, inf);
                    if(!que1.empty()) t1 = que1.front();
                    if(!que2.empty()) t2 = que2.front();

                    if(t1.fi < t2.fi) {
                        que1.pop();
                        int u = t1.se;
                        if(dd[u] < t1.fi) continue;
                        for(int v : mp[u]) {
                            if(dd[v] > dd[u] + 1) {
                                dd[v] = dd[u] + 1;
                                que2.push(pii(dd[v], v));   
                            }
                        }
                    }
                    else {
                        que2.pop();
                        int u = t2.se;
                        if(dd[u] < t2.fi) continue;
                        for(int v : mp[u]) {
                            if(dd[v] > dd[u] + 1) {
                                dd[v] = dd[u] + 1;
                                que2.push(pii(dd[v], v));
                            }
                        }
                    }
                }

                while(!que2.empty()) {
                    pii t2 = que2.front(); que2.pop();
                    int u = t2.se;
                    if(dd[u] < t2.fi) continue;
                    for(int v : mp[u]) {
                        if(dd[v] > dd[u] + 1) {
                            dd[v] = dd[u] + 1;
                            que2.push(pii(dd[v], v));
                        }
                    }
                }
                for(int i=1; i<=n; i++) sum = sum + dd[i];
            }
int main(){
            int T;
            scanf("%d", &T);
            int cas = 0;
            while(T--) {
                scanf("%d%d", &n, &m);
                memset(dis, inf, sizeof(dis));
                for(int i=1; i<=n; i++) mp[i].clear();
                for(int i=1; i<=m; i++) {
                    int u,v;
                    scanf("%d%d", &u, &v);
                    mp[u].pb(v);
                    mp[v].pb(u);
                }
                int c1;  scanf("%d", &c1);
                for(int i=1; i<=c1; i++) {
                    int x;  scanf("%d", &x);
                    bfs(x, i, 0);
                }
                int c2;  scanf("%d", &c2);
                for(int i=1; i<=c2; i++) {
                    int x;  scanf("%d", &x);
                    bfs(x, i, 1);
                }
                sum = 0;
                for(int i=1; i <= c1; i++) {
                    for(int j=1; j<=c2; j++) {
                        solve(i, j);
                    }
                }
                ll base = 1ll*c1*c2*n;
                ll gg = gcd(sum, base);
                printf("Case #%d: %lld/%lld\n", ++cas, sum/gg, base/gg);
            }
            return 0;
}
View Code

 

posted @ 2019-08-03 18:07  ckxkexing  阅读(152)  评论(0编辑  收藏  举报