码迷,mamicode.com
首页 > 其他好文 > 详细

【BZOJ】1001: [BeiJing2006]狼抓兔子

时间:2018-05-05 15:25:51      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:return   void   cap   最小割   题目   can   color   .com   include   

题目

传送门:QWQ

 

 

分析

  显然答案是最小割。

  然后dinic卡一卡过去了。

  其实是懒得写转对偶图:正解

   (dinic原来写的是vector,后来改的比较鬼畜

 

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5, INF=2e9;
struct Edge{
    int from,to,cap,flow;
};
int siz=0;
Edge edges[6*maxn]; int G[maxn][7];
int que[maxn]; 
int d[maxn], vis[maxn], cur[maxn];
int s,t;
void Addedge(int a,int b,int c){
   // edges.push_back((Edge){a,b,c,0}); edges.push_back((Edge){b,a,c,0});
   // int m=edges.size()-1; G[a].push_back(m-1); G[b].push_back(m);
   edges[siz++]=(Edge){a,b,c,0};  edges[siz++]=(Edge){b,a,c,0};
   G[a][++G[a][0]]=siz-2; G[b][++G[b][0]]=siz-1;
}
bool BFS(){
    memset(vis,0,sizeof(vis)); memset(que,0,sizeof(que));
    que[1]=s;
    d[s]=0; vis[s]=1;
    int l=1,r=2;
    while(l<r){
        int x=que[l]; l++;
        for(int i=1;i<=G[x][0];i++){
            Edge v=edges[G[x][i]];
            if(!vis[v.to] && v.flow<v.cap){
                vis[v.to]=1; d[v.to]=d[x]+1;
                que[r++]=v.to;
            }
        }
    }
    return vis[t];
}
int DFS(int x, int a){
    if(x==t || a==0) return a;
    int flow=0, f;
    for(int& i=cur[x]; i<=G[x][0]; i++){
        Edge& v=edges[G[x][i]];
        if(d[x]+1==d[v.to] && (f=DFS(v.to,min(a,v.cap-v.flow)))){
            v.flow+=f; edges[G[x][i]^1].flow-=f;
            if(!f) {d[v.to]=-1;continue;}
            flow+=f; a-=f;
            if(a==0) break; 
        }
    }
    return flow;
}
int Maxflow()
{
    int flow=0;
    while(BFS()){
        for(int i=0;i<maxn;i++) cur[i]=1;
        flow+=DFS(s,INF);
    }
    return flow;
}
inline int getint()
{
       int w=0,q=0;
       char c=getchar();
       while((c<0 || c>9) && c!=-) c=getchar();
       if (c==-)  q=1, c=getchar();
       while (c>=0 && c<=9) w=w*10+c-0, c=getchar();
       return q ? -w : w;
}
 
int main()
{
    int n,m; scanf("%d%d",&n,&m);
    if(n==1&&m==1){ puts("0"); return 0; 
    } 
    s=1; t=n*m; 
    int capp;
    for(int i=0;i<n;i++){
        for(int j=1;j<m;j++){
            capp=getint();
            Addedge(i*m+j,i*m+j+1,capp);
    //      printf("*** %d %d %d\n",i*m+j,i*m+j+1,capp); 
        }
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<=m;j++){
            capp=getint();
            Addedge(m*(i-1)+j,i*m+j,capp);
    //      printf("*** %d %d %d\n",m*(i-1)+j,i*m+j,capp); 
        }
    } 
    for(int i=1;i<n;i++){
        for(int j=1;j<m;j++){
            capp=getint();
            Addedge(m*(i-1)+j,i*m+j+1,capp);
    //      printf("*** %d %d %d\n",m*(i-1)+j,i*m+j+1,capp); 
        }
    }
    printf("%d\n",Maxflow());
    return 0;
}

 

 

 

【BZOJ】1001: [BeiJing2006]狼抓兔子

标签:return   void   cap   最小割   题目   can   color   .com   include   

原文地址:https://www.cnblogs.com/noblex/p/8994749.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!