Vijos1734 NOI2010 海拔 平面图最小割

建立平面图的对偶图,把最小割转化成最短路问题

Dijkstra算法堆优化

(被输入顺序搞WA了好几次T_T)

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5
  6 const int maxN=502;
  7 const int maxV=maxN*maxN;
  8 const int inf=0x3f3f3f3f;
  9
 10 struct Edge
 11 {
 12     int to,next;
 13     int dist;
 14     void assign(int t,int n,int d)
 15         { to=t; next=n; dist=d; }
 16 };
 17
 18 Edge elist[maxV*4];
 19 int head[maxV];
 20 int ecnt;
 21 int N;
 22 int dest;
 23
 24 void initEdge()
 25 {
 26     memset(head,-1,sizeof(head));
 27     ecnt=0;
 28 }
 29
 30 inline void addEdge(int from,int to,int dist)
 31 {
 32     elist[ecnt].assign(to,head[from],dist);
 33     head[from]=ecnt++;
 34 }
 35
 36 void input()
 37 {
 38     scanf("%d",&N);
 39     dest=N*N+1;
 40     initEdge();
 41     int w;
 42     for(int j=0;j<=N;j++)
 43         for(int i=1;i<=N;i++)
 44         {
 45             scanf("%d",&w);
 46             if(!j) addEdge(0,i,w);
 47             else if(j==N) addEdge(N*N+i-N,dest,w);
 48             else addEdge(N*j+i-N,N*j+i,w);
 49         }
 50     for(int j=1;j<=N;j++)
 51         for(int i=0;i<=N;i++)
 52         {
 53             scanf("%d",&w);
 54             if(!i) addEdge(N*j+1-N,dest,w);
 55             else if(i==N) addEdge(0,N*j,w);
 56             else addEdge(N*j+i+1-N,N*j+i-N,w);
 57         }
 58     for(int j=0;j<=N;j++)
 59         for(int i=1;i<=N;i++)
 60         {
 61             scanf("%d",&w);
 62             if(!j || j==N) continue;
 63             else addEdge(N*j+i,N*j+i-N,w);
 64         }
 65     for(int j=1;j<=N;j++)
 66         for(int i=0;i<=N;i++)
 67         {
 68             scanf("%d",&w);
 69             if(!i || i==N) continue;
 70             else addEdge(N*j+i-N,N*j+i+1-N,w);
 71         }
 72 }
 73
 74 struct Vertex
 75 {
 76     int idx;
 77     int dist;
 78     Vertex() {}
 79     Vertex(int i,int d):idx(i),dist(d) {}
 80     bool operator < (const Vertex& other) const
 81         { return this->dist > other.dist; }
 82 };
 83
 84 int dist[maxV];
 85 int open[maxV];
 86 std::priority_queue<Vertex> que;
 87
 88 int dijkstra()
 89 {
 90     memset(dist,0x3f,sizeof(dist));
 91     memset(open,1,sizeof(open));
 92     dist[0]=0; open[0]=false;
 93     int cur=0;
 94     while(cur!=dest)
 95     {
 96         for(int e=head[cur];e!=-1;e=elist[e].next)
 97         {
 98             int& to=elist[e].to;
 99             int& len=elist[e].dist;
100             if(open[to] && dist[to]>dist[cur]+len)
101             {
102                 dist[to]=dist[cur]+len;
103                 que.push(Vertex(to,dist[to]));
104             }
105         }
106         Vertex vt;
107         do { vt=que.top(); que.pop(); }
108         while(!open[vt.idx]);
109         cur=vt.idx;
110         open[cur]=false;
111     }
112     return dist[dest];
113 }
114
115 int main()
116 {
117     input();
118     printf("%d\n",dijkstra());
119     return 0;
120 }
时间: 2024-10-05 02:39:52

Vijos1734 NOI2010 海拔 平面图最小割的相关文章

BZOJ 2007 NOI2010 海拔 平面图最小割

题目大意:YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向道路连接主干道上两个相邻的交叉路口.下图为一张YT市的地图(n = 2),城市被划分为2×2个区域,包括3×3个交叉路口和12条双向道路. 小Z作为该市的市长,他根据统计信息得到了每天上班高峰期间YT市每条道路两个方向的人流量,即在高峰期间沿着

【BZOJ2007】【Noi2010】海拔 平面图最小割转最短路

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/43280891"); } 题解:这个模型很水,不需要极角序神马转对偶图,直接乱搞就行. 然后目的是把图割开,那么只需要跑S->T最短路就行. 要做平面图转对偶图不妨去这篇. [BZOJ2965]保护古迹 平面图转对偶图,暴力,网络流 还有就是某人

BZOJ 2007 NOI 2010 海拔 平面图最小割-&gt;最短路SPFA+pq

题目大意:给出一个城市各个道路的双向流量,城市的左上角的高度是0,城市的右下角的高度是1,若人流升高海拔就会消耗体力,问最小需要消耗多少体力. 思路:这道题才是真正的让我见识到了algorithm中的heap的强大. 分析这道题可以发现,一定会有一条分界线,这个分界线左边高度都为0,右边高度都是1,然后找到这条分界点就可以了.明显的最小割.但是数据量巨大,直接跑最大流会T,又是平面图,建立对偶图然后跑最短路,SPFA+pq在BZOJ上可以很快,如果有的OJ卡STL的话可以考虑SPFA+Heap,

BZOJ 2007 海拔(平面图最小割-最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.

【平面图最小割】BZOJ2007-[NOI2010]海拔

[题目大意] 城市被东西向和南北向的主干道划分为n×n个区域,包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路.现得到了每天每条道路两个方向的人流量.每一个交叉路口都有海拔,每向上爬h的高度,就需要消耗h的体力.如果是下坡的话,则不需要耗费体力.城市西北角的交叉路口海拔为0,东南角的交叉路口海拔为1.现在知道每条路两个方向的人流量,在最理想的情况下(即你可以任意假设其他路口的海拔高度),求每天所有人爬坡所消耗的总体力和的最小值. [思路] 显然是一个平面图最小割,最基础的平面图最

[bzoj1001][BeiJing2006]狼抓兔子-题解[平面图最小割转最短路]/[Dinic求最小割]

Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路

平面图最小割 对偶图

平面图最小割 对偶图: 平面图G的性质: (1)满足n个点,m条边,f个面 f = m - n + 2; (2)存在与其对应的对偶图G*; 对偶图:将原图中每个面变成一个点,外边界的无限大的面看成一个点,后连线即成对偶图: G的面数等于G*的点数,边数相等: 详解请看 最大最小定理(平面图最小割 对偶图)周冬 对于平面图的最大流(最小割)只需转化为对偶图,直接跑最短路即可: ps:觉得建图是最复杂的,各种RE(边数就是原来的边数,只是点数变成了原来的面数,,不注意就RE了):还有现在行数列数都变

【平面图最小割】BZOJ1001- [BeiJing2006]狼抓兔子

[题目大意]左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的.开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,如果一条道路上最多通过的兔子数为K,需要同样数量的K只狼伏击,求封锁道路的最小狼数. [思路]显然这是最小

tyvj P1209 - 拦截导弹 平面图最小割&amp;&amp;模型转化

P1209 - 拦截导弹 From admin    Normal (OI)总时限:6s    内存限制:128MB    代码长度限制:64KB 背景 Background 实中编程者联盟为了培养技术精湛的后备人才,必须从基础题开始训练. 描述 Description 某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试验阶段,所以只有