[BZOJ2007][NOI2010]海拔(对偶图最短路)
2024-08-27 16:10:43
首先确定所有点的海拔非0即1,问题转化成裸的平面图最小割问题,进而转化成对偶图最短路(同BZOJ1002)。
这题的边是有向的,所以所有边顺时针旋转90度即可。
如下图(S和T的位置是反的)。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; priority_queue<pair<int,int> > q; const int N=;
int x,S,T,h[N],to[N],val[N],nxt[N],cnt,dis[N],vis[N],n,num[][]; void add(int x,int y,int z){ to[++cnt]=y; val[cnt]=z; nxt[cnt]=h[x]; h[x]=cnt; } void work(){
memset(dis,0x3f,sizeof(dis)); dis[S]=;
q.push(make_pair(,S));
while(!q.empty()){
x=q.top().second; q.pop();
if(vis[x]) continue;
vis[x]=;
for(int i=h[x]; i; i=nxt[i])
if (dis[to[i]]>dis[x]+val[i])
dis[to[i]]=dis[x]+val[i],q.push(make_pair(-dis[to[i]],to[i]));
}
} int main(){
freopen("bzoj2007.in","r",stdin);
freopen("bzoj2007.out","w",stdout);
scanf("%d",&n); S=; T=n*n+;
rep(i,,n) num[][i]=num[i][n+]=S,num[i][]=num[n+][i]=T;
rep(i,,n) rep(j,,n) num[i][j]=n*(i-)+j;
rep(i,,n) rep(j,,n) scanf("%d",&x),add(num[i][j],num[i+][j],x);
rep(i,,n) rep(j,,n) scanf("%d",&x),add(num[i][j+],num[i][j],x);
rep(i,,n) rep(j,,n) scanf("%d",&x),add(num[i+][j],num[i][j],x);
rep(i,,n) rep(j,,n) scanf("%d",&x),add(num[i][j],num[i][j+],x);
work(); printf("%d\n",dis[T]);
return ;
}
最新文章
- PHP中常见的提示对照表
- XMLHttpRequest对象用法
- Windows 7下硬盘安装Ubuntu 14.04图文教程
- 在Nginx服务器中设置多个站点
- [问题2014S03] 解答
- WebForm和WinForm取当前根目录的通用的方法[转载]
- JavaScript的学习--正则表达式
- OOD、OOP、AOP区别
- PHP数据库
- SQL入门学习0-数据库与SQL
- 把对象转换成map
- C#smtp邮件消息提醒的一些bug总结
- unixbench 物理机性能与虚拟机性能测试对比
- Redis入门到高可用(七)——Hash
- 多线程——interrupt方法
- Exchange 2010 OWA部分用户不能访问
- ubuntu18.10安装redis遇到问题
- [Algorithm] Construct String from Binary Tree
- vue_表单_组件
- vue 阅读一【待完结】