zoukankan      html  css  js  c++  java
  • 2018.12.20-dtoj-4084-演艺(b)

     

    题目描述:

     

    一张 N 个点 M 条无向边的图,节点编号为 1 到 N,每条边具有一个正整数的长度。 

     

    假定黄花敦会从 S 点出发到达 T 点,并且只会走最短路,wxh 和 wsq 会在 A 点和 B 点 埋伏黄花敦。 

     

    为了保证一定能埋伏到黄花敦,同时 wxh 又想制造单独和黄花敦相处的机会,A 点和 B 点必须满足:黄花敦所有可能路径中,必定会经过 A 点和 B 点中的任意一点且不存在一条 路径同时经过 A 点和 B 点。 

     

    Wxh 想知道满足上面两个条件的 A,B 点对有多少个,交换 A,B 的顺序算相同的方案。

     

    算法:dijk,bitset,拓扑

    思路:

    首先先建出最短路网,在最短路网中拓扑处理出经过每个点的最短路条数,考虑对于满足条件的AB,经过A的条数与经过B的条数总和等于总最短路条数,且经过两点的条数不重复。

    我们有了每个点的最短路条数,考虑怎么把重复的点去掉。重复两点即至少有一条路径能从其中一个点到达另一个点,于是我们跑两遍拓扑,处理出谁能走到我和我能走到谁,即可能重复的点。

    然后我们用bitset维护,对于一个点,把权值等于(总最短路树-经过我的最短路数)的bitset和可能重复的点的bitset&起来,即重复的点,再用权值=(总最短路树-经过我的最短路数)的bitset^重复的点数,即可以与我匹配的点的数目,用.count()计算其中1的数目即可。效率是O(n2/32)

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=5e4+5,p=998244353;const LL inf=1e18;
    int n,m,s,T,head[N],ne[N<<1],to[N<<1],cnt,w[N<<1],tot;LL d[N],ds[N],dt[N],in[N],out[N];int iw[N],ow[N];LL ans;
    struct data{int l,r,w;}t[N];queue<int> Q;bitset<N> val[N],k[N],f,g[N];map<int,int> ma;
    struct node{int x;LL d;bool operator<(const node&t1)const{return d>t1.d;}};priority_queue<node> q;
    il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
    il void insert(int x,int y,int z){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;w[cnt]=z;}
    il void ins(int x,int y){in[y]++;ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;}
    il int mu(int x,int y){if(x+y>=p)return x+y-p;return x+y;}
    il void dijk(int S){
        for(int i=1;i<=n;i++)d[i]=inf;d[S]=0;q.push((node){S,d[S]});
        while(!q.empty()){
            node now=q.top();q.pop();int x=now.x;if(now.d!=d[x])continue;
            for(int i=head[x];i;i=ne[i]){
                if(d[to[i]]<=d[x]+w[i])continue;
                d[to[i]]=d[x]+w[i];q.push((node){to[i],d[to[i]]});
            }
        }
    }
    int main()
    {
        n=read();m=read();s=read();T=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read(),w=read();
            t[i]=(data){x,y,w};insert(x,y,w);insert(y,x,w);
        }
        dijk(s);for(int i=1;i<=n;i++)ds[i]=d[i];
        dijk(T);for(int i=1;i<=n;i++)dt[i]=d[i];
        for(int i=1;i<=n;i++)head[i]=0;cnt=0;
        for(int i=1;i<=m;i++){
            int x=t[i].l,y=t[i].r;
            if(ds[x]+dt[y]+t[i].w==ds[T])ins(x,y);
            if(dt[x]+ds[y]+t[i].w==ds[T])ins(y,x);
        }
        Q.push(s);iw[s]=1;
        while(!Q.empty()){
            int x=Q.front();Q.pop();k[x][x]=1;
            for(int i=head[x];i;i=ne[i]){
                iw[to[i]]=mu(iw[to[i]],iw[x]);k[to[i]]|=k[x];
                if(--in[to[i]]==0)Q.push(to[i]);
            }
        }
        for(int i=1;i<=n;i++)head[i]=0,in[i]=0;cnt=0;
        for(int i=1;i<=m;i++){
            int x=t[i].l,y=t[i].r;
            if(ds[x]+dt[y]+t[i].w==ds[T])ins(y,x);
            if(dt[x]+ds[y]+t[i].w==ds[T])ins(x,y);
        }
        Q.push(T);ow[T]=1;
        while(!Q.empty()){
            int x=Q.front();Q.pop();g[x][x]=1;
            for(int i=head[x];i;i=ne[i]){
                ow[to[i]]=mu(ow[to[i]],ow[x]);g[to[i]]|=g[x];
                if(--in[to[i]]==0)Q.push(to[i]);
            }
        }
        for(int i=1;i<=n;i++){
            iw[i]=1ll*iw[i]*ow[i]%p;
            if(!ma[iw[i]])ma[iw[i]]=++tot;
            val[ma[iw[i]]][i]=1;k[i][i]=1;
        }
        int sum=iw[T];
        for(int i=1;i<=n;i++){
            int R=ma[mu((sum-iw[i])%p,p)];
            f=val[R]&(k[i]|g[i]);
            f=val[R]^f;ans+=f.count();
        }
        printf("%lld
    ",ans>>1ll);
        return 0;
    }
    View Code

    //全场最慢...

  • 相关阅读:
    2016(4)数据库系统,ER模型,规范化理论,并发控制
    2016(3)系统设计,嵌入式系统
    2016(2)系统设计,面向对象设计方法,需求工程,面向对象需求分析
    2016(1)系统规划,可行性分析,成本效益分析
    2017(5)软件架构设计,web系统的架构设计,数据库系统,分布式数据库
    2017(4)数据库系统,分布式数据库,NoSQL,反规范化
    2017(3)系统设计,嵌入式多核程序设计
    2017(2)数据库设计,数据库设计过程,ER模型,规范化理论
    2017(1)软件架构,架构风格,微服务
    2018(5)软件架构设计,架构风格,REST
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10153614.html
Copyright © 2011-2022 走看看