P4001 [ICPC-Beijing 2006]狼抓兔子

题目链接


题解:
按照行列斜的关系和它们之间的权值建边然后直接跑最大流就OK了

注意是无向边,所以来回两条边的权值应该是一样的


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 6e6+50;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
int n,m,s,t,tot=1,head[MAXN],to[MAXN],w[MAXN],nxt[MAXN],h[MAXN];
inline void ade(int u,int v,int ww){
    to[++tot]=v; w[tot]=ww; nxt[tot]=head[u]; head[u]=tot;
}
inline void add(int u,int v,int w){ ade(u,v,w); ade(v,u,w); }
inline int bfs(){
    queue<int> que; que.push(s); memset(h,0,sizeof(h)); h[s]=1;
    while(!que.empty()){
        int u=que.front(); que.pop();
        for(int i=head[u];i;i=nxt[i]){
            if(w[i] && !h[to[i]]){
                h[to[i]]=h[u]+1; que.push(to[i]);
            }
        }
    }
    return h[t];
}
inline int dfs(int x,int f){
    if(x==t) return f; int fl=0;
    for(int i=head[x];i&&f;i=nxt[i]){
        if(w[i] && h[to[i]]==h[x]+1){
            int mi=dfs(to[i],min(f,w[i]));
            w[i]-=mi; w[i^1]+=mi; fl+=mi; f-=mi;
        }
    }
    if(!fl) h[x]=-1;
    return fl;
}
inline int dinic(){
    int res=0;
    while(bfs()) res+=dfs(s,INF);
    return res;
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
    scanf("%d%d",&n,&m); s=1,t=n*m;
    for(int i=1;i<=n;i++)
        for(int j=1,x;j<=m-1;j++)
            scanf("%d",&x),add(j+(i-1)*m,j+1+(i-1)*m,x);
    for(int i=1;i<=n-1;i++)
        for(int j=1,x;j<=m;j++)
            scanf("%d",&x),add(j+(i-1)*m,j+i*m,x);
    for(int i=1;i<=n-1;i++)
        for(int j=1,x;j<=m-1;j++)
            scanf("%d",&x),add(j+(i-1)*m,j+1+i*m,x);
    printf("%d\n",dinic());
    return 0;
}

P4001 [ICPC-Beijing 2006]狼抓兔子P4001 [ICPC-Beijing 2006]狼抓兔子 Nightmare丶 发布了178 篇原创文章 · 获赞 1 · 访问量 3371 私信 关注
上一篇:2008 Asia Regional Beijing Ping pong


下一篇:配置阿里云镜像源