zoukankan      html  css  js  c++  java
  • BZOJ1066[SCOI2007]蜥蜴

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1066

    感觉比较水的一道题。

    发现蜥蜴可以随便跳,然后柱子的高度对于能不能跳到并没有什么用,所以高度就是相当于每个柱子只允许hi只蜥蜴跳过它。

    所以高度就是这个柱子的限制次数,这不就是拆点后连hi的限制边,然后随便跑一个最大流就可以了么?...

    但是这题我SB开小了多次数组= =,你们知道这样建图最多有多少条边吗?...应该是n*m*d*d=400*16=6400吧?如果考虑拆点似乎只是+n*m?

    然后发现我开这么多也不能过,难道是因为源点和汇点的影响吗?...其实做完才发现,其实一个点最多可以连出去(2*d)^2*pi条边,所以是n*m*(2*d)*(2*d)=25600条边;然后一条双向边要*2,所以开51200是最好的咯?...

    反正我当时没想清,发现RE+TLE几次,于是索性就开了100000过了,而且因为是拆点,所以点的个数也要翻一倍,不要忘了。

    唔,又复习一遍dinic,感觉模板终于不会打错了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int maxn=22;
    const int maxt=810;
    const int INF=0x3f3f3f3f;
    
    struct Node{
        int data,next,low;
    }node[100010];
    
    #define now node[point].data
    #define then node[point].next
    #define www node[point].low
    
    int n,m,d,Idex,cnt;
    int s,t,tot;
    int head[maxt],cur[maxt];
    int dis[maxt],que[maxt];
    int ind[maxn][maxn];
    char m1[maxn][maxn],m2[maxn][maxn];
    
    void add(int u,int v,int w){
        node[cnt].data=v;node[cnt].next=head[u];node[cnt].low=w;head[u]=cnt++;
        node[cnt].data=u;node[cnt].next=head[v];node[cnt].low=0;head[v]=cnt++;
    }
    
    void init(int x,int y){
        if(x-d<=0 || y-d<=0 || x+d>n || y+d>m) add(ind[x][y]+Idex,t,INF);
        for(int i=max(1,x-d);i<=min(n,x+d);i++)
            for(int j=max(1,y-d);j<=min(m,y+d);j++)
                if(m1[i][j]>'0')
                    if(abs(i-x)+abs(j-y)<=d) add(ind[x][y]+Idex,ind[i][j],INF);
    }
    
    bool BFS(){
        memset(dis,-1,sizeof(dis));
        int H=0,T=1;que[1]=s,dis[s]=0;
        while(H<T){
            H++;
            for(int point=head[que[H]];point!=-1;point=then)
                if(www && dis[now]<0){
                    dis[now]=dis[que[H]]+1;
                    que[++T]=now;
                }
        }
        if(dis[t]<0) return false;
        return true;
    }
    
    int dfs(int x,int low){
        if(x==t) return low;
        int Low;
        for(int &point=cur[x];point!=-1;point=then)
            if(www && dis[now]==dis[x]+1){
                Low=dfs(now,min(low,www));
                if(Low){
                    www-=Low;node[point^1].low+=Low;
                    return Low;
                }
            }
        return 0;
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("1066.in","r",stdin);
        freopen("1066.out","w",stdout);
    #endif
    
        scanf("%d%d%d",&n,&m,&d);
        
        for(int i=1;i<=n;i++)
            scanf("%s",m1[i]+1);
        for(int i=1;i<=n;i++)
            scanf("%s",m2[i]+1);
    
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(m1[i][j]>'0') ind[i][j]=++Idex;
        
        t=(Idex<<1)+1;
        for(int i=s;i<=t;i++) head[i]=-1;
    
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(m1[i][j]>'0'){
                    add(ind[i][j],ind[i][j]+Idex,m1[i][j]-'0');
                    init(i,j);
                }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(m2[i][j]=='L')
                    add(s,ind[i][j],1),tot++;
        
        int flag,sum=0;
        while(BFS()){
            for(int i=s;i<=t;i++) cur[i]=head[i];
            while(1){
                flag=dfs(s,INF);
                if(!flag) break;
                sum+=flag;
            }
        }
        
        printf("%d",tot-sum);
        
        return 0;
    }
    View Code
  • 相关阅读:
    登陆跳转回原来页面
    magento获取当前浏览器的url和对url判断处理
    Magento获取购物车所有信息
    magento查询商品库存
    金额转换成0.00的形式
    Magento网站运行原理解析
    linux下如何禁用root账户直接登陆
    web前端常用的10个jQuery特效总结
    js函数
    网站css
  • 原文地址:https://www.cnblogs.com/Robert-Yuan/p/5215754.html
Copyright © 2011-2022 走看看