2015.9.11模拟赛 codevs4162 bzoj1774【无双大王】
无双大王hzwer扫清六合,席卷八荒,万姓倾心,四方仰德。
hzwer拥有一片领土,其中有n个城市和m条双向道路。他规定每个人在领土上行走都要交过路费,同时进城也要交进城费。不同道路的过路费可能不同,不同城市的进城费可能不同。但是hzwer规定,如果缴纳x的进城费,那么所有小于x的进城费就不用缴纳了。(即只缴纳一条路径上的所有过路费和最大的进城费)那么从s城市出发到t城市,要缴纳多少费用?(s城市和t城市进城费也要算)
第一行两个数n,m,q。表示n个城市m条路q个询问。
接下来n个数,表示n个城市的进城费。
接下来m行,每行3个数,表示一条路径的两端和过路费。
接下来q行,每行两个数s,t,表示询问从s到t的最小花费。
对于每个询问,输出一行表示最小花费。
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
8
9
对于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【无双大王】的更多相关文章
- 2015.9.11模拟赛 codevs 4160【会玩的】
题目描述 Description hzwer真的很会玩啊…他有一个n*m的方格,每次可以给方格添加一整行或一整列,但是不能删除.现在他想要让总格子数超过k个,但是又想让总格子数尽可能小.请找出这时的n ...
- 2015.9.11模拟赛 codevs 4159【hzwer的迷の数列】
题目描述 Description hzwer找了一个人畜无害的迷の数列…… 现在hzwer希望对这个数列进行一些操作,请你来回答hzwer的问题. 操作一:查询第i个数的大小 操作二:把第i个数的大小 ...
- NOIp 2015真题模拟赛 By cellur925
果然我还是最菜的==不接受反驳== Day1 T1:神奇的幻方 思路:直接模拟即可,由于当前放法只与上一放法有关系,用两个变量记录一下即可.10分钟内切掉== 预计得分:100分 实际得分:100分 ...
- 2019.11.11 模拟赛 T2 乘积求和
昨天 ych 的膜你赛,这道题我 O ( n4 ) 暴力拿了 60 pts. 这道题的做法还挺妙的,我搞了将近一天呢qwq 题解 60 pts 根据题目给出的式子,四层 for 循环暴力枚举统计答案即 ...
- ZROI 19.08.11模拟赛
传送门 写在前面:为了保护正睿题目版权,这里不放题面,只写题解. dlstql,wsl A \(10pts:\) \(a=100,T=100\),对每个排列构造一个反的,一步到位即可. \(20pts ...
- 11/1 NOIP 模拟赛
11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...
- 9.11 myl模拟赛
9.11 myl 模拟赛 100 + 100 + 0 第一题耗费了太多的时间,导致最后一题没有时间想,直接去写了暴力,而且出题人没有给暴力分.... Problem 1. superman [题目描述 ...
- NOIP模拟赛-2018.11.7
NOIP模拟赛 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 如果用命令行编译程序可以发现没加头文件之类的错误. 编译之前另存一份,听说如果敲 ...
- NOIP模拟赛-2018.11.6
NOIP模拟赛 今天想着反正高一高二都要考试,那么干脆跟着高二考吧,因为高二的比赛更有技术含量(我自己带的键盘放在这里). 今天考了一套英文题?发现阅读理解还是有一些困难的. T1:有$n$个点,$m ...
随机推荐
- jQuery实现密保互斥问题
密保互斥问题: 密保通常都会有n个问题,让用户选择其中2.3个,而且都不会让用户选择重复的问题.这就要求密保互斥. 效果如下: 下面我用了jquery实现密保互斥,用于解决密保,投票等类似互斥问题,可 ...
- Robotium--通过Id寻找控件
在自动化测试中,UI上经常有一些控件是没有名称的,那么此时,就可以通过id来找到这些控件. 案例:对两个EditText进行测试 package com.tangbc.tedit.test; impo ...
- [Falcor] Retrieving Multiple Values
In addition to being able to retrieve a path from a Falcor Model, you can also retrieve multiple Pat ...
- Java集合类具体解释
假设您喜欢这些文章,欢迎点击此处订阅本Blog 集合类说明及差别 Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Ma ...
- 【前端JS】input textarea 默认文字,点击消失
如题.前端页面的 input textarea 有时候须要显示默认文字以提示用户,下面为实现代码,以 input 为例.textarea 能够直接搬用 HTML <input type=&quo ...
- 大数据笔记02:大数据之Hadoop的生态系统和版本
1.Hadoop的生态系统: (1)图1: (2)图2: 图1 和 图2 都是形象说明了Hadoop的生态圈. 2.举例介绍Hadoop生态圈的小工具: (1)Hive工具(中文意思:小蜜蜂) 利用H ...
- 【iOS之轮播视图、自定义UIPageControl】
基于UISrollView实现的无限循环轮播视图. 实现的思路:使用三个UIImageView不断循环利用,始终将最中间一个View显示在UIScrolView的contentSize上,每次滚动后, ...
- 洛谷 P1412 经营与开发
/* 粘一下开始写的暴力吧 虽然没啥价值 */ #include<iostream> #include<cstdio> #include<cstring> #inc ...
- Try,Catch,Finally三块中如果有Return是怎么个运行顺序
今天看一个Java SSH的面试题,题目大概意思是:try.catch中存在return语句,还会执行finally块吗?如果执行,是return先执行还是finally先执行?如果有多个return ...
- CSS中伪类的使用
原文:http://www.cnblogs.com/guopei/archive/2011/04/16/2017627.html 何为伪类? 也就是实际实现了类的效果,但是并没有实际添加到标签中的类, ...