[NOI2010]海拔 平面图转对偶图 最小割

Code:

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 500002
int S=0,T=500001;
int idx;
int head[N];
int to[N];
int val[N];
int nex[N];
long long f[N];
int inq[N];
int x;
int n;
void addedge(int a,int b,int c)
{
	nex[++idx]=head[a];
	head[a]=idx;
	to[idx]=b;
	val[idx]=c;
}
int arr(int x,int y)
{
    if(x==0||y>n)
    	return S;
    if(x>n||y==0)
    	return T;
    return (x-1)*n+y;
}
struct Point
{
	int dis,number;
	inline bool operator < (const Point &a) const
	{
		return dis>a.dis;
	}
};
priority_queue < Point > q;
void dijkstra(int S)
{
	Point tmp;
	tmp.number=S;
	tmp.dis=0;
	for(int i=1;i<N;i++)
		f[i]=1e16;
	f[tmp.number]=0;
	q.push(tmp);
	while(!q.empty())
	{
		int x=q.top().number;
		q.pop();
		if(inq[x])
			continue;
		inq[x]=0;
		for(int i=head[x];i;i=nex[i])
		{
			if(f[to[i]]>f[x]+val[i]&&(!inq[to[i]]))
			{
				f[to[i]]=f[x]+val[i];
				tmp.dis=f[to[i]];
				tmp.number=to[i];
				q.push(tmp);
			}
		}
	}
}
int main()
{
	freopen("arrange.in","r",stdin);
	freopen("arrange.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n+1;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&x);
			addedge(arr(i-1,j),arr(i,j),x);
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n+1;j++)
		{
			scanf("%d",&x);
			addedge(arr(i,j),arr(i,j-1),x);
		}
	for(int i=1;i<=n+1;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&x);
			addedge(arr(i,j),arr(i-1,j),x);
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n+1;j++)
		{
			scanf("%d",&x);
			addedge(arr(i,j-1),arr(i,j),x);
		}
	dijkstra(S);
	printf("%lld",f[T]);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/9877375.html