zoukankan      html  css  js  c++  java
  • [USACO07FEB]Lilypad Pond

    只有新加的荷叶才会被统计,原来就有的荷叶不算在方案数里

    因为原来有的荷叶直接可以跳,不需要花费,所以不把它与它可以跳到的点连边,而是把它作为中转节点,把它可以到达的所有点互相连边,最后转化为最短路计数。

    还有一种情况。两个原本就有的荷叶可以相互到达的情况,此时就相当于有两个中转节点,需要把它们可以到达的至多16个点互相连边(用bfs解决)。


    Code:

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    #define ll long long
    #define INF 0x3f3f3f3f
    #define N 100
    
    template<class T>
    inline void read(T &x){
        x=0;char c=getchar();T flag=1;
        while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        x*=flag;
    }
    
    struct E{
        int next,to;
        ll dis;
    }e[(N*N)<<4];
    
    int dx[10]={-2,-2,-1,-1,1,1,2,2},
        dy[10]={-1,1,-2,2,-2,2,-1,1};
    int n,m,a[N][N],s,t,top,sta[N*N],head[N*N],cnt;
    bool in[N*N],vis[N*N],mark[N*N][N*N];
    ll dis[N*N],ans[N*N];
    queue<int> Q;
    
    inline bool check(int x,int y){
        if(x<1||x>n||y<1||y>m) return 0;
        if(a[x][y]==2) return 0;
        return 1;
    }
    inline void add(int id,int to,int dis){
        e[++cnt]=(E){head[id],to,dis};
        head[id]=cnt;
    } 
    void dfs(int x,int y){
        for(int op=0;op<8;op++){
            int xx=x+dx[op],yy=y+dy[op];
            if(!check(xx,yy)) continue;
            if(!a[xx][yy]&&!in[(xx-1)*m+yy]){
                in[(xx-1)*m+yy]=1;
                sta[++top]=(xx-1)*m+yy;
            }
            if(a[xx][yy]==1&&!vis[(xx-1)*m+yy]){
                vis[(xx-1)*m+yy]=1;
                dfs(xx,yy);
            }
        }
    }
    void bfs(){
        memset(dis,INF,sizeof(dis));
        memset(vis,0,sizeof(vis));
        Q.push(s);
        ans[s]=1,dis[s]=0,vis[s]=1;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for(int i=head[u];i;i=e[i].next){
                int v=e[i].to;
                if(dis[v]==dis[u]+e[i].dis){
                    ans[v]+=ans[u];
                    if(!vis[v]&&v!=t){
                        vis[v]=1;
                        Q.push(v);
                    }
                }
                if(dis[v]>dis[u]+e[i].dis){
                    dis[v]=dis[u]+e[i].dis;
                    ans[v]=ans[u];
                    if(!vis[v]&&v!=t){
                        vis[v]=1;
                        Q.push(v);
                    }
                }
            }
        }
    }
    int main(){
    //    freopen("chess.in","r",stdin);
    //    freopen("chess.out","w",stdout);
        read(n),read(m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                read(a[i][j]);
                if(a[i][j]==3){
                    s=(i-1)*m+j;
                    a[i][j]=0;
                }
                if(a[i][j]==4){
                    t=(i-1)*m+j;
                    a[i][j]=0;
                }
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(a[i][j]) continue;
                for(int op=0;op<8;op++){
                    int x=i+dx[op],y=j+dy[op];
                    if(check(x,y)&&(!a[x][y]))
                        add((i-1)*m+j,(x-1)*m+y,1);
                }
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(a[i][j]==1&&(!vis[(i-1)*m+j])){
                    top=0;
                    memset(in,0,sizeof(in));
                    vis[(i-1)*m+j]=1;
                    dfs(i,j);
                    for(int k=1;k<=top;k++)
                        for(int p=k+1;p<=top;p++)
                            if(!mark[sta[k]][sta[p]]){
                                mark[sta[k]][sta[p]]=mark[sta[p]][sta[k]]=1;
                                add(sta[k],sta[p],1),add(sta[p],sta[k],1);
                            }
                }
        bfs();
        if(!ans[t]) printf("-1");
        else printf("%lld\n%lld",dis[t]-1,ans[t]);
    }
    /*
    3 4
    3 0 0 0
    0 0 1 4
    2 2 2 0
    */
    
  • 相关阅读:
    Jmeter接口测试与数据驱动
    Jmeter内存溢出
    Mac下多版本pip共存
    Linux命令: ps
    intellij ultimate2019.3 注册
    纪念已经逝去的十年
    H3C路由器设置NAT回环、端口回流
    理清PHP在Linxu下执行时的文件权限
    windows下vagrant的安装使用
    无限极分类(adjacency list)的三种方式(迭代、递归、引用)
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/11409071.html
Copyright © 2011-2022 走看看