Luogu P4001 [ICPC-Beijing 2006]狼抓兔子

Link
平面图的最小割等于其对偶图的最短路。
虽然我不会证但感觉确实挺好理解的。

#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<utility>
#include<functional>
#define pi pair<int,int>
#define fi first
#define se second
namespace IO
{
    char ibuf[(1<<21)+1],*iS,*iT;
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
}
using IO::read;
using std::pair;
const int N=1007,M=N*N*2;
std::vector<pi>e[M];std::priority_queue<pi,std::vector<pi>,std::greater<pi>>q;
int id[N][N][2],dis[M],vis[M];
void add(int u,int v,int w){e[u].push_back({v,w}),e[v].push_back({u,w});}
int main()
{
    int n=read(),m=read(),s=1,t=2,c=2;memset(dis,0x7f,sizeof dis);
    for(int i=1;i<n;++i) for(int j=1;j<m;++j) id[i][j][0]=++c,id[i][j][1]=++c;
    for(int i=1;i<m;++i) id[n][i][0]=s,id[0][i][1]=t;
    for(int i=1;i<n;++i) id[i][0][0]=s,id[i][m][1]=t;
    for(int i=1;i<=n;++i) for(int j=1;j<m;++j) add(id[i-1][j][1],id[i][j][0],read());
    for(int i=1;i<n;++i) for(int j=1;j<=m;++j) add(id[i][j-1][0],id[i][j][1],read());
    for(int i=1;i<n;++i) for(int j=1;j<m;++j) add(id[i][j][0],id[i][j][1],read());
    q.push({dis[s]=0,s});
    for(int u;!q.empty();)
    {
	u=q.top().second,q.pop();if(vis[u])continue;vis[u]=1;
	for(pi x:e[u]) if(dis[x.fi]>dis[u]+x.se) q.push({dis[x.fi]=dis[u]+x.se,x.fi});
    }
    printf("%d",dis[t]);
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12235931.html