[BeiJing2006]狼抓兔子 平面图最小割

挺有意思的结论,对偶图中的一个环对应原图中一种割,把边流量转为距离跑最短路就是最小割了

//#include<bits/stdc++.h>  
//#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
  
const double pi=acos(-1.0);  
#define ll long long  
#define pb push_back

#define sqr(a) ((a)*(a))
#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))

const double eps=1e-10;
const int maxn=2e6+56;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;

int n,m;
int from,to;

struct EDGE{int v,w;};
vector<EDGE>G[maxn];
void addedge(int u,int v,int w){
	G[u].pb((EDGE){v,w});
	G[v].pb((EDGE){u,w});
}
struct NODE{
	int v,d;
	friend bool operator<(NODE a,NODE b){return a.d>b.d;}
};
int d[maxn],vis[maxn];
void dij(int from,int to){
	for(int i=0;i<maxn;i++)d[i]=inf;
	d[from]=0;
	priority_queue<NODE>Q;
	NODE now=(NODE){from,0};
	Q.push(now);
	while(!Q.empty()){
		NODE now=Q.top();Q.pop();
		int u=now.v;
		if(vis[u])continue;
		vis[u]=1;
		for(int i=0;i<G[u].size();i++){
			if(d[G[u][i].v]>d[u]+G[u][i].w){
				d[G[u][i].v]=d[u]+G[u][i].w;
				NODE nxt=(NODE){G[u][i].v,d[G[u][i].v]};
				Q.push(nxt);
			}
		}
	}
	printf("%d\n",d[to]);
}

int main(){
	while(~scanf("%d%d",&n,&m)){
		from=0;to=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?from:(2*(i-1)-1)*(m-1)+j;
				y=i==n?to:(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?to:(2*(i-1))*(m-1)+j-1;
				y=j==m?from:(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);
			}
		}
		dij(from,to);
	}
}


posted @ 2017-10-03 01:34  Drenight  阅读(120)  评论(0编辑  收藏  举报