题解:
求平面图的最小割。
转成对偶图求最短路。
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn=2000010; const int inf=1e9; int N,M; int s,t; struct e { int from; int to; int next; int flow; }edge[maxn*4]; int head[maxn]; int tol; void addedge (int u,int v,int flow) { edge[tol].from=u; edge[tol].to=v; edge[tol].next=head[u]; edge[tol].flow=flow; head[u]=tol++; edge[tol].from=v; edge[tol].to=u; edge[tol].next=head[v]; edge[tol].flow=flow; head[v]=tol++; } struct node { int v,w; }cur,tail; bool operator < (node a,node b) { return a.w>b.w; } int d[maxn]; int visit[maxn]; void dijkstra (int s,int t) { for (int i=0;i<maxn;i++) d[i]=inf; memset(visit,0,sizeof(visit)); d[s]=0; priority_queue<node> q; cur.v=s; cur.w=0; q.push(cur); while (!q.empty()) { cur=q.top(); q.pop(); int x=cur.v; if (visit[x]) continue; visit[x]=1; for (int i=head[x];i!=-1;i=edge[i].next) { if (d[edge[i].to]>d[x]+edge[i].flow) { d[edge[i].to]=d[x]+edge[i].flow; tail.v=edge[i].to; tail.w=d[edge[i].to]; q.push(tail); } } } printf("%d\n",d[t]); } int main () { while (~scanf("%d%d",&N,&M)) { memset(head,-1,sizeof(head)); tol=0; s=0; t=2*(N-1)*(M-1)+1; int x,y,cost; for (int i=1;i<=N;i++) { for (int j=1;j<M;j++) { scanf("%d",&cost); x=i==1?s:(2*(i-1)-1)*(M-1)+j; y=i==N?t:(2*(i-1))*(M-1)+j; addedge(x,y,cost); } } for (int i=1;i<N;i++) { for (int j=1;j<=M;j++) { scanf("%d",&cost); x=j==1?t:(2*(i-1))*(M-1)+j-1; y=j==M?s:(2*(i-1))*(M-1)+j-1+M; addedge(x,y,cost); } } for (int i=1;i<N;i++) { for (int j=1;j<M;j++) { scanf("%d",&cost); x=(2*(i-1))*(M-1)+j; y=(2*(i-1)+1)*(M-1)+j; addedge(x,y,cost); } } dijkstra(s,t); } return 0; }