省选专练NOI2010海拔

本文深入探讨了平面图上的最大流算法实现,通过构造对偶图并运用Dijkstra算法寻找最短路径来解决复杂网络流问题。文章详细介绍了算法的具体步骤,包括边的添加、最短路径的计算及关键数据结构的定义。

模板

平面图上最大流。

平面图转对偶图:旋转边90度

注意跑dijkstra的最短路

卡SPFA

#include<bits/stdc++.h>
using namespace std;
const int N=3e5;
const int INF=1e9+7;
struct Front_star{
	int u,v,w,nxt;
}e[N*4];
int cnt=1;
int first[N]={0};
void add(int u,int v,int w){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].nxt=first[u];
	first[u]=cnt;
}
//void add(int u,int v,int w){
//	addedge(u,v,w);
//	addedge(v,u,0);
//}
int n;
int S=0;
//int T=250000+2;
#define T n*n+2
struct Node{
	int u,w;
};
priority_queue<Node> q;
bool operator <(Node A,Node B){
	return A.w>B.w;
}
int dis[N]={0};
void dijkstra(){
	for(int i=S;i<=T;i++){
		dis[i]=INF;
	}
	dis[S]=0;
	q.push((Node){S,0});
	while(!q.empty()){
		Node tmp=q.top();
//		cout<<tmp.u<<" "<<tmp.w<<'\n';
		q.pop();
		int x=tmp.u;
		for(int i=first[x];i;i=e[i].nxt){
			int v=e[i].v;
//			cout<<e[i].w<<'\n';
			if(dis[x]+e[i].w<dis[v]){
				dis[v]=dis[x]+e[i].w;
				q.push((Node){v,e[i].w+tmp.w});
			}
		}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=0;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			int x;
			scanf("%d",&x);
			if(i==0) add(i*n+j,T,x);
			else if(i==n) add(S,i*n-n+j,x);
			else add(i*n+j,i*n-n+j,x);
		}
//	cout<<"88888"<<endl; 
	for(int i=1;i<=n;i++)
		for(int j=0;j<=n;j++)
		{	
			int x;
			scanf("%d",&x);
			if(j==0) 
				add(S,i*n-n+1,x);
			else 
				if(j==n) 
					add(i*n-n+j,T,x);
			else 
				add(i*n-n+j,i*n-n+j+1,x);
		}
	for(int i=0;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			int x;
			scanf("%d",&x);
			if(i==0) 
				add(T,i*n+j,x);
			else 
				if(i==n) 
					add(i*n-n+j,S,x);
			else 
				add(i*n-n+j,i*n+j,x);
		}
	for(int i=1;i<=n;i++)
		for(int j=0;j<=n;j++)
		{
			int x;
			scanf("%d",&x);
			if(j==0) 
				add(i*n-n+1,S,x);
			else 
				if(j==n) 
					add(T,i*n-n+j,x);
			else 
				add(i*n-n+j+1,i*n-n+j,x);
		}
	dijkstra();
	cout<<dis[T];
} 

转载于:https://www.cnblogs.com/Leo-JAM/p/10079277.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值