• 【NOIP模拟赛】chess 建图+spfa统计方案数


    似乎弗洛伊德和迪杰斯特拉都干不了统计方案数,spfa的话就是不断入队就好。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define get_hash(a,b) (a-1)*m+b
    const int N=55;
    const int Inf=0x3f3f3f3f;
    int t1[8]={-1,-2,-2,-1,1,2,2,1},t2[8]={-2,-1,1,2,2,1,-1,-2};
    int f[N*N],dis[N*N],n,s[N][N],m,hash[N][N],S,E,all;
    bool in[N*N],v[N][N],is[N*N],edge[N*N][N*N];
    inline bool ok(int x,int y){
        return x>0&&x<=n&&y>0&&y<=m&&s[x][y]!=2;
    }
    struct V{
        int to,next;
    }c[N*N*N*N];
    int head[N*N],t;
    std::queue<int>q;
    inline void add(int x,int y){
        c[++t].to=y,c[t].next=head[x],head[x]=t;
    }
    void dfs(int x,int y){
        if(v[x][y])return;
        v[x][y]=1;
        for(int i=0,p1,p2;i<8;i++){
            p1=x+t1[i],p2=y+t2[i];
            if(ok(p1,p2)==false)continue;
            if(s[p1][p2]==1)dfs(p1,p2);
            else is[hash[p1][p2]]=true;
        }
    }
    void read_build(){
        scanf("%d%d",&n,&m),all=n*m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                scanf("%d",&s[i][j]),hash[i][j]=get_hash(i,j);
                if(s[i][j]==3)S=hash[i][j];
                if(s[i][j]==4)E=hash[i][j];
            }
        for(int i=1,p1,p2;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(s[i][j]!=2&&s[i][j]!=4)
                    if(s[i][j]==1){
                        memset(is,0,sizeof(is)),dfs(i,j);
                        for(int x=1;x<=all;x++)
                            if(is[x]&&x!=E)
                                for(int y=1;y<=all;y++)
                                    if(x!=y&&is[y])
                                        edge[x][y]=true;
                    }
                    else
                        for(int k=0;k<8;k++){
                            p1=t1[k]+i,p2=t2[k]+j;
                            if(ok(p1,p2)&&s[p1][p2]!=1)
                                add(hash[i][j],hash[p1][p2]);
                        }
        for(int i=1;i<=all;i++)
            for(int j=1;j<=all;j++)
                if(i!=j&&edge[i][j])
                    add(i,j);
    }
    void spfa_print(){
        q.push(S),memset(dis,0x3f,sizeof(dis)),dis[S]=0,f[S]=1,in[S]=true;
        while(!q.empty()){
            int x=q.front();q.pop(),in[x]=false;
            for(int i=head[x];i;i=c[i].next)
                if(dis[x]+1<dis[c[i].to]){
                    dis[c[i].to]=dis[x]+1,f[c[i].to]=f[x];
                    if(in[c[i].to]==false)q.push(c[i].to),in[c[i].to]=true;
                }
                else if(dis[x]+1==dis[c[i].to]){
                    f[c[i].to]+=f[x];
                    if(in[c[i].to]==false)q.push(c[i].to),in[c[i].to]=true;
                }
        }
        if(f[E]==0)printf("-1");
        else printf("%d
    %d",dis[E]-1,f[E]);
    }
    int main(){
        read_build(),spfa_print();
        return 0;
    }
  • 相关阅读:
    HDU-5514 Frogs 容斥
    2019ICPC EC-FINAL H-King 随机
    2019ICPC EC-FINAL E-Flow 贪心
    洛谷P4200 千山鸟飞绝 Splay
    CodeForces 1249F Maximum Weight Subset 树形dp
    HDU-5534 Partial Tree 完全背包优化
    【数论】Lucas定理
    [APIO2009]抢掠计划 解题报告
    tarjan(缩点)
    树状数组总结
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7617799.html
Copyright © 2020-2023  润新知