More than 2019 cattle off summer school camp (sixth) H: Train Driver (shortest + probability)

The meaning of problems: Given an undirected graph, Alice is selected from a set of points A, Bob is selected from a set of point B, CXK select a point in the corpus. Then ask expectations "three to a minimum distance of a point of collection," the.

Thinking: did a bare title is given three position, and asked where to go from the set minimum price. That question is the three-point run three times SPFA, you can update the answer. And this question has a Cxk, very troublesome, however, noted that the right side is 1, tm is not directly BFS expand on it yet. Enumeration position Alice and Bob, then dis [i] = disA [i ] + disB [j], can then be expanded. Be careful not to over this with a log can be a problem.

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=200010;
const int inf=1e9;
int disA[21][maxn],disB[21][maxn],a[maxn],b[maxn];
int Laxt[maxn],Next[maxn],To[maxn],cnt,N; ll sum;
void add(int u,int v)
{
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void BFS(int dis[],int st)
{
    rep(i,1,N) dis[i]=inf; dis[st]=0;
    queue<int>q; q.push(st);
    while(!q.empty()){
        int u=q.front(); q.pop();
        for(int i=Laxt[u];i;i=Next[i]){
            if(dis[To[i]]==inf){
                dis[To[i]]=dis[u]+1;
                q.push(To[i]);
            }
        }
    }
}
int num[maxn],c[maxn],dis[maxn];
void solve() //基数排序+两个单调队列
{
    rep(i,0,N+N) num[i]=0;
    rep(i,0,N) num[dis[i]]++,d[i]=0;
    rep(i,1,N+N) num[i]+=num[i-1];
    rep(i,1,N) c[num[dis[i]]--]=i;
    queue<int>q1,q2;
    rep(i,1,N) q1.push(c[i]);
    while(!q1.empty()||!q2.empty()){
        if(q2.empty()||(!q1.empty()&&!q2.empty()&&dis[q1.front()]<dis[q2.front()])) {
            int u=q1.front(); q1.pop();
            for(int i=Laxt[u];i;i=Next[i]) {
                if(dis[To[i]]>dis[u]+1) {
                    dis[To[i]]=dis[u]+1;
                    q2.push(To[i]);
                }
            }
        }
        else {
            int u=q2.front(); q2.pop();
            for(int i=Laxt[u];i;i=Next[i]) {
                if(dis[To[i]]>dis[u]+1) {
                    dis[To[i]]=dis[u]+1;
                    q2.push(To[i]);
                }
            }
        }
    }
    rep(i,1,N) sum+=dis[i];
}
int main()
{
    int C=0,T,M,A,B,u,v;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&M);
        rep(i,1,N) Laxt[i]=0; cnt=0;
        rep(i,1,M){
           scanf("%d%d",&u,&v);
           add(u,v); add(v,u);
        }
        scanf("%d",&A); rep(i,1,A) scanf("%d",&a[i]);
        scanf("%d",&B); rep(i,1,B) scanf("%d",&b[i]);
        rep(i,1,A) BFS(disA[i],a[i]);
        rep(i,1,B) BFS(disB[i],b[i]);
        sum=0;
        rep(i,1,A)
         rep(j,1,B){
             rep(k,1,N) dis[k]=disA[i][k]+disB[j][k];
             solve();
        }
        ll ans=1LL*A*B*N;
        ll g=__gcd(ans,sum);
        printf("Case #%d: ",++C);
        if(g==sum) printf("%lld\n",sum/g);
        else printf("%lld/%lld\n",sum/g,ans/g);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/hua-dong/p/11306550.html