喵呜的虚拟城市(最短路)

Problem C: 虚拟城市

Time Limit: 2 Sec  Memory Limit: 128 MB

Submit: 5  Solved: 2

[Submit][Status][Web
Board
]

Description

虚拟城市是一个基于Windows平台的2D经营策略游戏。你可以在游戏中建造各种各样的建筑(公园、雕塑、喷泉、小屋、公寓、办公区、商场写字楼、综合办公楼、办公大楼、现代化摩天大楼等)、道路,也可以销毁他们, 当然建造、销毁它们都要花费资金,你可以通过每月的税收赚钱,就像专业的大型策略游戏一样。

在游戏中,公共运输系统很重要的,所以你需要在城市里建造车站,然后指派巴士在不同的车站之间往返。而且车站是有容量的,也就是说每个车站会有一个人数上限,如果想改变这个上限就需要升级或者降级车站。

现在在游戏中,你已经建造了n个车站,其中1号车站位于体育场门口,n号车站位于剧场门口,还有一些巴士,会把一个车站的人带往另一个车站。注意这里的巴士都是单行的,即如果他负责把x号车站的乘客带往y号车站,他就不负责把y号车站的乘客带往x号车站。当然,如果x号车站的容量小于y号车站,这样y号车站的容量就得不到充分的利用,你并不想看到这种情况发生,所以就会停运这趟巴士。

因此,现在人们想从体育场通过未停运的巴士到达剧场,在这之前,你可以通过对每个车站容量进行升级或者降级,使得重新规划后未停运的巴士可以将他们从体育场运输到剧场,当然,升级或降级都是有花费的,每次升级消耗1金币,将车站的容量上升1,降级也是一样的,每次消耗1金币,车站容量下降1,当然,你也不希望花费的金币太多,因此,你希望知道,最少花费多少金币能使得人们可以通过城市的公共交通系统从体育场到达剧场。

Input

第一行输入一个数T,表示测试数据个数,对于每组测试数据,第一行输入两个数n, m(2<=n<=50, 0<=m<=n*(n-1)),表示有n个车站,且这n个车站之间共存在m辆巴士。接下来,输入m行,每行两个数x, y(1<=x, y<=n),表示x和y之间有一辆巴士,且如果容量满足v(x)>=v(y)时,这辆巴士不会被停运,即可以将人们从x输送至y,但是无论容量怎么变,这辆车是不负责将人们从y输送至x。题目保证x和y不相同,也保证不会有两辆巴士有相同的起点和终点。接下来一行输入n个数,表示初始状态下n个车站的容量。(1<=v(i)<=10^9)

Output

对于每组测试数据,输出一个数,表示能让人们可以通过城市的公共交通系统从体育场到达剧场的最小花费,如果无论如何都到达不了,输出-1。

Sample Input

33 41 22 12 33 230 20 102 21 22 110 203 21 22 110 10 10

Sample Output

010-1

HINT

Hint

第一组数据,人们可以直接通过1->3这辆巴士从体育场直达剧场,第1个车站的容量大于等于第3个车站的容量,因此这辆巴士是可以乘坐的,因此花费为0。

第二组数据,存在1->2的巴士,但是第1个车站的容量小于第2个车站的容量,因此这辆巴士是停运的,你可以把这两个车站的容量都变成15,这样花费的代价为|10-15|+|20-15|=10,最小。注意,巴士的起点和终点的高度相同时也是可以运行的。

第三组数据,因为没有可以到达剧场的巴士,因此输出-1。

分析:首先,最终的情形一定是这样,每个车站的容量一定为v(1)~v(n)中的一个,那么可以把一个车站分成n个点,然后根据v(x)>=v(y)连边构图。最后跑一遍最短路即可。

构图: 加入一个超级源点0,源点0与起点车站1所分成的n个点相连,那么车站1形成的点即为1~n,形成的边即为0->i,边的权值即为abs(v(1)-v(i))。依此类推,对于车站x->y,如果v(i) >= v(j),那么连边 (x-1)*n+i -> (y-1)*n+j,权值为abs(v(y)-v(j))。

代码清单:

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;

const int maxn = 2500 + 5;
const int maxv = 200000 + 5;
const ll max_dis = 1e18 + 5;

int T;
int n,m,a,b;
int tmap[55][55];
int dist[55];
ll dis[maxn];

struct Edge{
    int to,dis;
    Edge(){}
    Edge(int to,int dis){
        this -> to = to;
        this -> dis = dis;
    }
};
vector<Edge>graph[maxn];

typedef pair<int,int>P;

void init(){
    memset(tmap,0,sizeof(tmap));
    for(int i=0;i<maxn;i++)
        graph[i].clear();
}

void input(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d",&a,&b);
        tmap[a][b]=1;
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&dist[i]);
}

//把一个点分成n个点,然后连边
void add(int u,int v){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dist[i]>=dist[j])
                graph[(u-1)*n+i].push_back(Edge((v-1)*n+j,abs(dist[j]-dist[v])));
        }
    }
}

void createGraph(){
    for(int i=1;i<=n;i++){
        graph[0].push_back(Edge(i,abs(dist[i]-dist[1])));
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(tmap[i][j]){
                add(i,j);
            }
        }
    }
}

ll dijkstra(int s){
    fill(dis,dis+maxn,max_dis);
    priority_queue<P,vector<P>,greater<P> >q;
    while(!q.empty()) q.pop();
    dis[s]=0;
    q.push(P(0,s));
    while(!q.empty()){
        P p=q.top();q.pop();
        int u=p.second;
        if(p.first>dis[u]) continue;
        for(int i=0;i<graph[u].size();i++){
            Edge& e=graph[u][i];
            if(dis[e.to]>dis[u]+e.dis){
                dis[e.to]=dis[u]+e.dis;
                q.push(P(dis[e.to],e.to));
            }
        }
    }
    ll ans=max_dis;
    //车站n所形成的点是(n-1)*n+1~n*n
    for(int i=(n-1)*n+1;i<=n*n;i++){
        ans=min(ans,dis[i]);
    }
    if(ans==max_dis) return -1;
    return ans;
}

void solve(){
    createGraph();
    printf("%lld\n",dijkstra(0));
}

int main(){
    //freopen("cin.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        init();
        input();
        solve();
    }return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-21 00:21:52

喵呜的虚拟城市(最短路)的相关文章

使用Three.js绘制一个虚拟城市

这篇文章解释了如何使用代码来编写一座3D立体“城市”.这个代码是由@ mrdoob最新发布的演示Demo.我发现这个演示的算法很优雅,是一个简单而有效的解决方案,所以我发了一个帖子解释它. 关于算法的一些评论 在我们将关注焦点置于问题的细节之前,把握下问题的整体和全局是很有帮助的.这个3D虚拟城市所使用的算法是完全由程序所生成的,这意味着整个城市 是动态建立,而不参考任何模板.这个算法相当优雅,且不超过100行javascript代码.这个算法的原理是怎么样的呢?简而言之,每一个建筑是一个 立方

SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题——Jason niu

%SA:利用SA算法解决TSP(数据是14个虚拟城市的横纵坐标)问题--Jason niu X = [16.4700 96.1000 16.4700 94.4400 20.0900 92.5400 22.3900 93.3700 25.2300 97.2400 22.0000 96.0500 20.4700 97.0200 17.2000 96.2900 16.3000 97.3800 14.0500 98.1200 16.5300 97.3800 21.5200 95.5900 19.4100

HDU 5521 Meeting(虚拟节点+最短路)

Meeting Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1358    Accepted Submission(s): 435 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer Jo

无尽虚拟城市来了!Demo可走可飞,“波函数坍缩”开源算法蹿红

神说,要有光. 于是有了光. 神说,要有一座城. 于是有了一座城. 神说,这座城要无限大. 神啊你别再说了,那是另外的价钱. 不过,有种叫做波函数坍缩 (Wave Collapse Function) 的算法,可以让一座白茫茫的城,在虚拟世界里无限延伸. 你跑得再快,飞得再远,都到不了它的尽头. 因为,这座城可以实时扩张,你往哪里走,它就往哪里生成,不会让你跑出去的. 而它背后的波函数坍缩 (WFC) 算法自诞生以来,每隔一段时日,便会引起人类蜂拥而至的关注. 不管是因为这赏心悦目的应用: 还是

Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)

1741. Communication Fiend Time limit: 1.0 second Memory limit: 64 MB Kolya has returned from a summer camp and now he's a real communication fiend. He spends all his free time on the Web chatting with his friends via ICQ. However, lately the protocol

360虚拟场景展示 让异域他乡之美浮现眼前

虚拟全景又称三维全景虚拟现实(也称实景虚拟)是基于全景图像的真实场景虚拟现实技术.全景(英文名称是 Panorama)是把相机环360 度拍摄的一组或多组照片拼接成一个全景图像,通过计算机技术实现全方位互动式观看的真实场景还原展示方式. 应用领域方面可广泛应用于房地产三维电子楼书设计.宾馆酒店展示.旅游景点展示.城市景观展现,也可以应用于电子商务网上的虚拟展厅制作.网上虚拟博物馆的展示.政府虚拟城市项目建设以及包括建筑设计和施工单位在内的各大中型企业的企业形象宣传和项目记录与汇报等方面. 酷雷曼

Unity3D制作3D虚拟漫游场景(一)

开始前先说一些题外话,本来这个工程是已经完成了超过一半了,然而由于手残重装了系统不小心删除了,现在只好再做一遍了.顺便写一下博供今后写代码参考. 这是一款使用unity3D开发的虚拟城市漫游游戏,实际上博主是非常喜欢这类游戏的,在城市里面自由地去浪是多么随意的一件事(雾). 最近VR和AR莫名火起来了,然而穷到吃土,入手了Google cardboard,店家顺便附赠了蓝牙游戏遥控器,这款游戏我会在完成之后移植到VR上面进行测试. 博主家在新乡,是的没错,前几天发洪水能划船的新乡,耽误了一些时间

先做一个“小程序”——关于微信应用号的六大猜想

先做一个“小程序”——关于微信应用号的六大猜想 9月 21 日,苦等了9个多月的时间,应用号终于与我们见面了,命名为「小程序」. 01 为什么推出小程序? 考虑到小程序对整个APP市场的影响,毫无疑问会对现有的APP生态带来一定的冲击.但是,之所以推出小程序,最直接的原因可能是为了构建和扩充微信生态链,让微信更具开放性. 如我们所知,目前微信公众号分为三类: • 服务号,连接人和商品,目前很多电商企业,以及在微信端提供产品和服务的企业都用服务号. • 订阅号,微信官方的定位是阅读,连接人和资讯的

7000个源码批量下载---复制来的

7000个源码批量下载 7000个源码批量下载 < type="text/javascript" language="JavaScript">document.title="7000个源码批量下载 - "+document.title http://asp.lt263.com/soft/SaGuestBook.rar 安全天使字符界面留言本(SaGuestBook)http://asp.lt263.com/soft/lbs.rar L