2018多校第三场 hdu6331 M :Walking Plan
题目链接 hdu6331
自我吐槽,这场多校大失败,开局签到因输入输出格式写错,wa了3发。队友C题wa了1个小时,还硬说自己写的没错,结果我随便造了个小数据,他都没跑对。然后跑对了后又进入了无限的卡常之中,幸好最后卡过去了。
G题我头铁写了个单侧凸壳,不对输入数据判重,而是在加入凸壳时判断,结果wa到比赛结束,进而导致I没时间写。M题开局看错题意直接丢了。最后从30多名掉到了150。这大概就是菜得安详吧 ̄ω ̄=
题意
给定n个点m条有向边,q次查询,每次查询问走至少k条边的,s到t的最短路径的长度,边可以重复走。
q=100000,n=50,m<=10000,k<=10000..
这题用矩阵快速幂啥的复杂度爆炸
细节
1.首先最基本的,要先对边去重留下最短边。
2.这里有个细节要注意一下,在某些情况下 s 到t距离,只有在走过的边数达到某个周期后才有解。
比如n个点组成一条有向环,则1到2距离只有在走过数边数k=1,n+1,2n+1 。周期也就是环的长度。
所以查询k时,答案的路径边数范围会在k到n+k之间。
3.任意两点的最短距离的边数小于n
预处理
首先预处理两个数组。g[k][s][t] 代表恰好走k条边后s到t的最短路径。
k=1,2,……10000.
这个用Floyd跑全部数据复杂度要k*n*n*n=12.5亿=GG。 这显然是不行的,所以只能分块,我取块长为100,即只让k=1,2,3,……100。但相邻二维数组之间间隔100条边。则复杂降低至1250万。
接着就是怎么处理块内了。
dis[k][s][t] 代表走大于等于k条边后s到t的最短路径。
k=1,2,……100 。
这个处理方式时先用floyd跑到k=200, 再逆向for 令dis[k][s][t]=min(dis[k][s][t],dis[k+1][s][t])这样就能保证在k=1,2,3……100时答案是正确的。
因为大于等于k的最坏情况,就是从s到达了点z,接着还要跑(z,t)之间的最短路才能到达t. 而最短路D的边数最多就n-1。 其实更新n项后就一定就正确了。所以溢出100项,只是写的顺手。
查询
对于k<=100的查询我们可以直接用dis数组回答复杂度O(1)
对于k>100的查询,令 k=q*100+r 其中1<=r<=100
则答案就是min(g[q][s][z]+dis[r][z][t]) 。其中z是我们枚举的中间点。 这样就能保证查询到的答案是大于等于k的,且答案是正确的。单次查询复杂度O(n)
AC代码
、
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int dis[][][];
int g[][][];
int INF=1e9,n;
int get(int s,int t,int k)
{
if(k<=)
{
return dis[k][s][t];
}
else
{
register int i,q,r,ans=INF; q=(k-)/;
r=k-*q;
//printf("%d %d \n",q,r);
for(i=; i<=n; i++)
{
ans=min(ans,dis[r][s][i]+g[q][i][t]);
}
return ans;
}
}
int main()
{
int m,t,x,y,w,q,ans;
register int i,j,k,l;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(dis,,sizeof(dis));
memset(g,,sizeof(g));
INF=dis[][][];
// printf("%d\n",INF);
for(i=; i<=n; i++)
{
for(j=; j<=n; j++)
{
dis[][i][j]=INF;
}
}
while(m--) {
scanf("%d%d%d",&x,&y,&w);
dis[][x][y]=min(dis[][x][y],w);
}
for(i=; i<=; i++)
{
for(j=; j<=n; j++)
{
for(k=; k<=n; k++)
{
for(l=; l<=n; l++)
{
dis[i][j][k]=min( dis[i][j][k],dis[i-][j][l]+dis[][l][k]);
}
}
}
}
for(i=; i<=n; i++)
{
for(j=; j<=n; j++)
{
g[][i][j]=dis[][i][j];
}
}
for(i=; i<=; i++)
{
for(j=; j<=n; j++)
{
for(k=; k<=n; k++)
{
for(l=; l<=n; l++)
{
g[i][j][k]=min( g[i][j][k],g[i-][j][l]+g[][l][k]);
}
}
}
}
for(i=; i>=; i--)
{
for(j=; j<=n; j++)
{
for(k=; k<=n; k++)
{
dis[i][j][k]=min( dis[i][j][k],dis[i+][j][k]);
}
}
}
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d",&x,&y,&k);
ans=get(x,y,k);
if(ans<=INF/)
{
printf("%d\n",ans);
}
else
{
puts("-1");
}
}
} return ;
}
HDU6331
话说我写的这么暴力,在ac代码里居然不算很慢的︿( ̄︶ ̄)︿
2018多校第三场 hdu6331 M :Walking Plan的更多相关文章
- 2018 HDU多校第三场赛后补题
2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...
- 牛客多校第三场 F Planting Trees
牛客多校第三场 F Planting Trees 题意: 求矩阵内最大值减最小值大于k的最大子矩阵的面积 题解: 矩阵压缩的技巧 因为对于我们有用的信息只有这个矩阵内的最大值和最小值 所以我们可以将一 ...
- 牛客多校第三场 G Removing Stones(分治+线段树)
牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...
- 2019 牛客暑期多校 第三场 F Planting Trees (单调队列+尺取)
题目:https://ac.nowcoder.com/acm/contest/883/F 题意:求一个矩阵最大面积,这个矩阵的要求是矩阵内最小值与最大值差值<=m 思路:首先我们仔细观察范围,我 ...
- 2018 Multi-University Training Contest 3 杭电多校第三场
躺了几天 终于记得来填坑了 1001 Ascending Rating (hdoj 6319) 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6319 ...
- 2018年多校第三场第一题 A. Ascending Rating hdu6319
比赛地址:http://acm.hdu.edu.cn/contests/contest_show.php?cid=804 题目编号:第一题 A. Ascending Rating hdu6319 题 ...
- 2018牛客多校第三场 C.Shuffle Cards
题意: 给出一段序列,每次将从第p个数开始的s个数移到最前面.求最终的序列是什么. 题解: Splay翻转模板题.存下板子. #include <bits/stdc++.h> using ...
- 2018杭电多校第三场1003(状态压缩DP)
#include<bits/stdc++.h>using namespace std;const int mod =1e9+7;int dp[1<<10];int cnt[1& ...
- hdu-4893-Wow! Such Sequence!-线段树【2014多校第三场-J】
题意:一个初始为0的数组,支持三种操作:1.向第k个数添加d,(|d| < 2^31);2.把[l, r]区间内的数字都换成与它最相近的Fibonacci数;3.询问[l, r]区间的和. 思路 ...
随机推荐
- 学习python第十二天,函数4 生成器generator和迭代器Iterator
在Python中,这种一边循环一边计算的机制,称为生成器:generator 要创建一个generator,有很多种方法.第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个genera ...
- 1016-02-首页17-添加转发微博控件-计算转发配图的 Frame-------打印出 被转发微博的模型
说明:HWStatus为微博模型,_retweeted_status 为返回的数据( 一条微博模型)里面的一个属性,_retweeted_status 不为空表示此微博是否转发了其他微博._retwe ...
- caioj:1093: 并查集2(scy的删边问题) C++
题目描述 [题目描述] 读入一个无向图(可能含有多个连通分支),输出最多能删掉多少条边,而不改变这个图任意两点的连通性(原来连通的两个点依然连通,不连通的依然不连通). [输入格式] 第一行为图的顶点 ...
- python搭建友盟以及个推推送web服务器
一.友盟客户端demo: 由于SDK原因,新版Android Studio的Android API 28 Platform无法同步新建项目, 所以我最终选择下载android-studio-bundl ...
- 单源次短路径:poj:3255-Roadblocks
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17521 Accepted: 6167 Descripti ...
- [CodeForces - 296D]Greg and Graph(floyd)
Description 题意:给定一个有向图,一共有N个点,给邻接矩阵.依次去掉N个节点,每一次去掉一个节点的同时,将其直接与当前节点相连的边和当前节点连出的边都需要去除,输出N个数,表示去掉当前节点 ...
- 使用windows live writer写cnblog-1 安装wlr
Writer:在本地编辑有声在色的博客内容,发布到你的网络博客! 离线安装文件下载地址:http://dx1.itopdog.cn/soft/wlsetup-all.rar 下了好几个离线版本的, ...
- Git-Git克隆
鸡蛋不装在一个篮子里 Git的版本库目录和工作区在一起,因此存在一损俱损的问题,即如果删除一个项目的工作区,同时也会把这个项目的版本库删除掉.一个项目仅在一个工作区中维护太危险了,如果有两个工作区就会 ...
- MySQL 5.7远程连接
将/etc/mysql/my.cnf中的bind_address那一行注释掉或修改为"bind_address=0.0.0.0": bind_address并没有在/etc/mys ...
- 1- js vue.js
1 js 2 Vue.js