题目描述 Description

无双大王hzwer扫清六合,席卷八荒,万姓倾心,四方仰德。

hzwer拥有一片领土,其中有n个城市和m条双向道路。他规定每个人在领土上行走都要交过路费,同时进城也要交进城费。不同道路的过路费可能不同,不同城市的进城费可能不同。但是hzwer规定,如果缴纳x的进城费,那么所有小于x的进城费就不用缴纳了。(即只缴纳一条路径上的所有过路费和最大的进城费)那么从s城市出发到t城市,要缴纳多少费用?(s城市和t城市进城费也要算)

输入描述 Input Description

第一行两个数n,m,q。表示n个城市m条路q个询问。

接下来n个数,表示n个城市的进城费。

接下来m行,每行3个数,表示一条路径的两端和过路费。

接下来q行,每行两个数s,t,表示询问从s到t的最小花费。

输出描述 Output Description

对于每个询问,输出一行表示最小花费。

样例输入 Sample Input

5 7 2
2 5 3 3 4
1 2 3
1 3 2
2 5 3
5 3 1
5 4 1
2 4 3
3 4 4
1 4
2 3

样例输出 Sample Output

8

9

数据范围及提示 Data Size & Hint

对于20%数据,1<=n<=10.

对于60%数据,1<=n<=100.

对于100%数据,1<=n<=250,1<=m,q<=10000

 

题意是给定一个只有双向边的连通图,点有点权,边有边权,定义一条路径的费用是这条路径上的边权和加路径上的点权的最大值,询问两点之间的最小费用

看到n=250不难想到floyd.但是很容易发现,由于点权的影响,单纯地cost[i,k]+cost[k,j]到cost[i,j]的转移是不行的。

假设从点1到点2有两条路,一条dist=1,maxv=7.另一条dist=4,maxv=5.则第一条费用是8,第二条费用是9,我们会选择第1条。

但是假设从点2到点3有一条路,dist=3,maxv=4,容易看出一开始选第一条路费用是1+7+3=13,选第二条路费用是4+5+3=12.所以第2条会更优。

如果用个max[i,j]存i到j的最小费用路径上的点权最大值再想办法转移之类的也是不行的,因为不能转移的本质原因是不知道最大点权的点的位置,而求最短路又和路径有关。因此没办法判断最大点是否在某一段路径上,也就不能转移。除非再开一维保存最大点权的位置,才可以转移。那样复杂度就到n^4以上了。

回归到floyd的原型,其实就是个dp。f[i][j][k]表示从i到j的路径上除了两端点只经过编号1到k的点时的距离最小值。那么f[i][j][k]=min(f[i][j][k-1],f[i][k][k-1]+f[k][j][k-1]).最后一维因为总是从上一状态转移而来所以可以省略。

那么考虑floyd的枚举顺序,当我们枚举k,i,j时,经过的点只有i,j,还有编号1到k的k个点。如果按照点权从小到大排个序,那么编号为k的点比其他1到k中的点的点权都大。

所以只要点权考虑v[i],v[j],v[k]的最大值即可,而边权同floyd。

ps:"如果是一棵树的话,闲的没事还可以用link cut tree来做"——by hzwer

conclusion:一开始看到这道题的时候,我也没有从这方面去想。题目没有什么外延想法或者结论,只利用了floyd的性质,并从这一点出发,应该说整个思路都是很自然的。但是我们在背模板的时候,在为10分钟打出了无脑的线段树平衡树树套树而沾沾自喜的时候,是否注意到了这些算法背后的东西?如果没有积累一点深刻的认识,恐怕再简单不过的东西都能把你考倒。

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 0x7fffffff
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
#define N 1010
using namespace std;
inline LL read()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct srt{int x,rnk;}cdk[];
bool operator <(srt a,srt b){return a.x<b.x;}
int dis[][];
int ans[][];
int v[];
int n,m,q;
int main()
{
memset(dis,/,sizeof(dis));
memset(ans,/,sizeof(ans));
for (int i=;i<=n;i++)dis[i][i]=;
n=read();m=read();q=read();
for (int i=;i<=n;i++)
{
cdk[i].rnk=i;
cdk[i].x=read();
v[i]=cdk[i].x;
}
sort(cdk+,cdk+n+);
for (int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
dis[x][y]=min(dis[x][y],z);
dis[y][x]=min(dis[y][x],z);
}
for (int kk=;kk<=n;kk++)
{
int k=cdk[kk].rnk;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
if (k!=i&&k!=j&&i!=j)
{
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
ans[i][j]=min(ans[i][j],dis[i][j]+max(max(v[i],v[j]),v[k]));
}
}
for (int i=;i<=q;i++)
{
int x=read(),y=read();
printf("%d\n",ans[x][y]);
}
}

codevs4162 && bzoj1774

2015.9.11模拟赛 codevs4162 bzoj1774【无双大王】的更多相关文章

  1. 2015.9.11模拟赛 codevs 4160【会玩的】

    题目描述 Description hzwer真的很会玩啊…他有一个n*m的方格,每次可以给方格添加一整行或一整列,但是不能删除.现在他想要让总格子数超过k个,但是又想让总格子数尽可能小.请找出这时的n ...

  2. 2015.9.11模拟赛 codevs 4159【hzwer的迷の数列】

    题目描述 Description hzwer找了一个人畜无害的迷の数列…… 现在hzwer希望对这个数列进行一些操作,请你来回答hzwer的问题. 操作一:查询第i个数的大小 操作二:把第i个数的大小 ...

  3. NOIp 2015真题模拟赛 By cellur925

    果然我还是最菜的==不接受反驳== Day1 T1:神奇的幻方 思路:直接模拟即可,由于当前放法只与上一放法有关系,用两个变量记录一下即可.10分钟内切掉== 预计得分:100分 实际得分:100分 ...

  4. 2019.11.11 模拟赛 T2 乘积求和

    昨天 ych 的膜你赛,这道题我 O ( n4 ) 暴力拿了 60 pts. 这道题的做法还挺妙的,我搞了将近一天呢qwq 题解 60 pts 根据题目给出的式子,四层 for 循环暴力枚举统计答案即 ...

  5. ZROI 19.08.11模拟赛

    传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. dlstql,wsl A \(10pts:\) \(a=100,T=100\),对每个排列构造一个反的,一步到位即可. \(20pts ...

  6. 11/1 NOIP 模拟赛

    11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...

  7. 9.11 myl模拟赛

    9.11 myl 模拟赛 100 + 100 + 0 第一题耗费了太多的时间,导致最后一题没有时间想,直接去写了暴力,而且出题人没有给暴力分.... Problem 1. superman [题目描述 ...

  8. NOIP模拟赛-2018.11.7

    NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...

  9. NOIP模拟赛-2018.11.6

    NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...

随机推荐

  1. pat 1049. Counting Ones (30)

    看别人的题解懂了一些些    参考<编程之美>P132 页<1 的数目> #include<iostream> #include<stdio.h> us ...

  2. Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)

    大连游戏产业不是很发达,最后,选择一个应用程序外包公司.积累的工作和学习过程中的一点业余生活微信体验,我想分享的游戏小朋友的爱. 在应用开发过程中会经常实用户上传头像的功能,在网上找了N多资料发现没有 ...

  3. json 项目应用

    package com.founder.ec.dec.action; import java.net.URLEncoder; import java.util.HashMap; import java ...

  4. ProGuard 代码混淆

    简介 Java代码是非常容易反编译的.为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理. ProGuard是一个混淆代码的开源项目.它的主要作用就是混淆,当然它还能对字节码 ...

  5. CSS 命名规则

    CSS书写顺序: 位置属性(position, top, right, z-index,display, float等) 大小(width, height, padding, margin) 文字系列 ...

  6. MVC的Model层中的一些便签

    由于自己重新接触MVC,所以把Model层里的一些标签给记录下来,方便自己的使用. 这些是自己目前试用过的一些,在以后的工作中我会接着补充进去新的内容

  7. akka

    akka学习 http://www.cnblogs.com/libaoheng/archive/2012/03/19/2406836.html

  8. mysql limit性能问题

    offset大的时候的比较 1. SELECT * FROM persons LIMIT 200000,10; 耗时0.109s 2. SELECT *FROM persons WHERE id> ...

  9. GridView and DropDownList

    <form id="form1" runat="server"> <div> <asp:GridView runat=" ...

  10. Skin++ 皮肤库 CCheckListBox MFC 界面风格

    今天使用CCheckListBox,发现增加进去的字符串无法显示,但是当点击的时候,确有反应. 仔细检查代码,没有问题.之前也是这样用的,完全没有问题. 思前想后,觉得是因为使用了Skin++皮肤库, ...