zoukankan      html  css  js  c++  java
  • 【BZOJ2007】[Noi2010]海拔 对偶图最短路

    【BZOJ2007】[Noi2010]海拔

    Description

    YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域。简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形。从而,YT城市中包括(n+1)×(n+1)个交叉路口和2n×(n+1)条双向道路(简称道路),每条双向 道路连接主干道上两个相邻的交叉路口。下图为一张YT市的地图(n = 2),城市被划分为2×2个区域,包括3×3个交叉路口和12条双向道路。

    小Z作为该市的市长,他根据统计信息得到了每天上班高峰期间YT市每条道路两个方向的人流量,即在高峰期间沿 着该方向通过这条道路的人数。每一个交叉路口都有不同的海拔高度值,YT市市民认为爬坡是一件非常累的事情,每向上爬h的高度,就需要消耗h的体力。如果 是下坡的话,则不需要耗费体力。因此如果一段道路的终点海拔减去起点海拔的值为h(注意h可能是负数),那么一个人经过这段路所消耗的体力是max{0, h}(这里max{a, b}表示取a, b两个值中的较大值)。

    小Z还测量得到这个城市西北角的交叉路口海拔为0,东南角的交叉路口海拔为1(如上图所示),但其它交叉路口的海拔高度都无法得知。小Z想知道在最理想的情况下(即你可以任意假设其他路口的海拔高度),每天上班高峰期间所有人爬坡消耗的总体力和的最小值。

    Input

    第一行包含一个整数n,含义如上文所示。

    接下来4n(n + 1)行,每行包含一个非负整数分别表示每一条道路每一个方向的人流量信息。输入顺序:n(n + 1)个数表示所有从西到东方向的人流量,然后n(n + 1)个数表示所有从北到南方向的人流量,n(n + 1)个数表示所有从东到西方向的人流量,最后是n(n + 1)个数表示所有从南到北方向的人流量。对于每一个方向,输入顺序按照起点由北向南,若南北方向相同时由西到东的顺序给出(参见样例输入)。

    Output

    仅包含一个数,表示在最理想情况下每天上班高峰期间所有人爬坡所消耗的总体力和(即总体力和的最小值),结果四舍五入到整数。

    Sample Input

    1 1 2 3 4 5 6 7 8

    Sample Output

    3

    HINT

    对于20%的数据:n ≤ 3;

    对于50%的数据:n ≤ 15;

    对于80%的数据:n ≤ 40;

    对于100%的数据:1 ≤ n ≤ 500,0 ≤ 流量 ≤ 1,000,000且所有流量均为整数。

    【提示】

    海拔高度不一定是整数。

    题解:对偶图最短路,把每个方格看成点,从西向东的路看成从上到下的边,从东向西的路看成从下到上的边,从北向南看成从右到左,从南向北看成从左到右,东、北边界为起点,西、南边界为终点,然后跑最短路

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <queue>
    #define P(A,B)	((A-1)*n+B)
    using namespace std;
    int n,m,cnt,ans,S,T;
    int to[1010000],next[1010000],val[1010000],dis[250010],vis[250010],head[250010];
    priority_queue<pair<int,int> > pq;
    int rd()
    {
    	int ret=0;	char gc=getchar();
    	while(gc<'0'||gc>'9')	gc=getchar();
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret;
    }
    void add(int a,int b,int c)
    {
    	to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
    }
    int main()
    {
    	scanf("%d",&n);
    	S=0,T=n*n+1;
    	int i,j,u;
    	memset(head,-1,sizeof(head));
    	for(i=1;i<=n+1;i++)	for(j=1;j<=n;j++)	add((i==1)?S:P(i-1,j),(i>n)?T:P(i,j),rd());
    	for(i=1;i<=n;i++)	for(j=1;j<=n+1;j++)	add((j>n)?S:P(i,j),(j==1)?T:P(i,j-1),rd());
    	for(i=1;i<=n+1;i++)	for(j=1;j<=n;j++)	add((i>n)?T:P(i,j),(i==1)?S:P(i-1,j),rd());
    	for(i=1;i<=n;i++)	for(j=1;j<=n+1;j++)	add((j==1)?T:P(i,j-1),(j>n)?S:P(i,j),rd());
    	memset(dis,0x3f,sizeof(dis));
    	pq.push(make_pair(0,S)),dis[S]=0;
    	while(!pq.empty())
    	{
    		u=pq.top().second,pq.pop();
    		if(vis[u])	continue;
    		vis[u]=1;
    		for(i=head[u];i!=-1;i=next[i])
    		{
    			if(dis[to[i]]>dis[u]+val[i])
    			{
    				dis[to[i]]=dis[u]+val[i];
    				pq.push(make_pair(-dis[to[i]],to[i]));
    			}
    		}
    	}
    	printf("%d",dis[T]);
    	return 0;
    }
  • 相关阅读:
    codeblocks-17.12mingw-nosetup(mingw编译,绿色免安装版)的下载、安装及设置一
    我的Qt历程1:第一个Qt程序
    单一职责-依赖倒转-代理模式-迭代器模式等
    结合你以往的工作经验谈谈高并发应用的性能优化措施
    如何优化数据库,如何提高数据库的性能?
    在一个千万级的数据库查询中,如何提高查询效率?
    如何提高页面的显示速度?假如一个页面的加载时间是10.89s,你会用什么方式进行优化?
    强制提高网站性能有什么办法
    简述httpModule与HttpHandler
    EntityFramework的效率与ADO.Net的效率哪个高?
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6527097.html
Copyright © 2011-2022 走看看