[BZOJ1001]-狼抓兔子 Dinic模板题

来源:互联网 发布:json保存学生资料 编辑:程序博客网 时间:2024/05/19 17:58

一道貌似要用对称图然后跑spfa的题,然而貌似高标预流推进却是跑得最快的·····
用dinic也可以过,就当是一道模板题练练手····加了当前弧优化


题目传送门:BZOJ1001
写还是很容易的,但是有两个需要注意的地方····
第一个是建边,因为题中是双向边,因此正反向边都需要流量,而不是正向有反向0这样建

贴一份代码
Accepted 94604 kb 1372 ms 2295 B

#include<cstring>#include<algorithm>#include<cstdio>#include<queue>using namespace std;const int INF=0x3f3f3f3f;struct path{    int pre,to,flow;}p[7000000];int N,M,tp=1,head[1000001],dep[1000001],cur[1000001];int totpoint;inline void read( int &res ){    char ch = getchar(); res = 0;    while(ch < '0' || ch > '9') {ch = getchar();}    while(ch >= '0' && ch <= '9') res = res * 10 + ch - 48, ch = getchar();}void In(int t1,int t2,int t4){    p[++tp].pre=head[t1];    p[tp].to=t2;    p[tp].flow=t4;    head[t1]=tp;}void read_in(){    int t4,addnow,qppnow;    scanf("%d%d",&N,&M);totpoint=N*M;    for(register int i=0;i<N;i++){        addnow=i*M;qppnow=addnow+1;        for(register int j=1;j<M;j++){            read(t4);            In(addnow+j,qppnow+j,t4);            In(qppnow+j,addnow+j,t4);        }    }    for(register int i=1;i<N;i++){        addnow=(i-1)*M;qppnow=addnow+M;        for(register int j=1;j<=M;j++){            read(t4);            In(addnow+j,qppnow+j,t4);            In(qppnow+j,addnow+j,t4);        }    }    for(register int i=1;i<N;i++){        addnow=(i-1)*M;qppnow=addnow+M+1;        for(register int j=1;j<M;j++){            read(t4);            In(addnow+j,qppnow+j,t4);            In(qppnow+j,addnow+j,t4);        }    }}bool Bfs(){    memset(dep,0,sizeof(dep));    queue<int> q;    dep[1]=1;    q.push(1);    while(!q.empty()){        int u=q.front();q.pop();        for(int i=head[u];i;i=p[i].pre){            int v=p[i].to;            if(!dep[v]&&p[i].flow){                dep[v]=dep[u]+1;                q.push(v);            }        }    }    return (dep[totpoint]!=0);}int Dfs(int u,int pref){    if ( u == totpoint || ! pref )        return pref;    int nowf = 0 ;    for(int &i=cur[u];i;i=p[i].pre){        int v=p[i].to,q,r=min(p[i].flow,pref);        if(dep[v]!=dep[u]+1||p[i].flow <= 0)    continue;        if(q=Dfs(v,r)){            p[i].flow-=q;            p[i^1].flow+=q;            pref-=q;            nowf+=q;            if(pref==0) break;        }    }    if(!nowf)   dep[u]=-1;    return nowf;}long long Dinic(){    long long flow=0;    while(Bfs()){        for(int i=1;i<=totpoint;i++)            cur[i]=head[i];        flow+=(long long)Dfs(1,INF);    }    printf("%lld",flow);}int main(){    read_in();    Dinic();}