「SDOI 2009」Elaxia的路线
发现自己这几天智商完全不在线……
这道题的数据十分的水,怎样都可以艹过去……
开始想了一个完全错误的算法,枚举一对点,判断这一对点是否同时在两条最短路上,是就用两点之间的路径更新答案。显然这样是错的:
8 10
7 8 2 5
1 3 1
3 5 2
3 6 2
3 8 4
5 8 4
6 8 2
5 6 4
6 2 9
7 5 7
6 7 9
答案显然是 0,但是这个算法会输出 3。
但是实际上这个做法是可以 AC 的,但是我只有 30 分,原因先按下不表。
然后点开了讨论,发现我的做法果然是错的,然后发现正解是枚举一条边然后判断是否在公共最短路上,然后再在这些边中找最长链。
好的,没问题,差不太多,改一下就行。
改完交一发,还是 WA。
再看讨论区的做法明明和我一样,凭什么不让老子过?
然后我又发现这个做法也被 hack 了,就在我刚看到的这个做法的地方下面一点点。
艹,我刚才为什么不把讨论区看完?
因为我判断一条边是否在最短路上还是判断这条边链接两点是否在最短路上,这样依然是错的:
4 5
1 2 3 4
1 2 2
1 3 2
1 4 2
2 4 3
2 3 1
可以发现点1,2在公共最短路上,但是边1-2却不在公共最短路上。
我天真的以为是数据加强了,于是去找题解。结果发现百度第一篇题解 TM 就是上面的错误做法?终于,我找到了 PoPoQQQ 的题解,他的做法是没有问题的。
正确的做法是判断 \(dis[s][u]+w+dis[v][t] = dis[s][t]\),因为样例两人实际上是反向走的,所以要分别考虑 \(s1\) -> \(t1\) 和 \(s2\) -> \(t2\) 最长的重合部分与 \(s1\) -> \(t1\) 和 \(t2\) -> \(s2\)
的最长的重合部分。
注意不能一次计算,下面给一组讨论区 hack 数据:
8 9
1 6 7 8
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
7 3 5
7 5 5
2 8 4
4 8 4
然后,我重写了一遍,一遍过掉了样例,信心满满的交了一发,TM 还是 30 分。
接着我上面那组数据把自己 hack 掉了。
不对,我测过 PoPoQQQ 的代码,它可以过这组数据啊,那么一定是我细节写错了……
震惊!【SDOI 2009】Elaxia的路线始终 30 分的原因竟是——
dijkstra 求最短路的时候这样子写:
priority_queue <int> q;
以点的编号而不是到源点的距离为关键字……
这样居然还能过样例……
服气,无 fuck 说……
而上面的三种做法(没错包括第一种)只要我把 dijkstra 写对就能 AC。
吃枣药丸。
#include <bits/stdc++.h>
using namespace std;
#define RG register
#define N 2000
#define M 2500000
#define inf 536870912
inline int gi()
{
RG int ret; RG char ch;
ret=0, ch=getchar();
while (ch < '0' || ch > '9')
ch=getchar();
while (ch >= '0' && ch <= '9')
ret=(ret<<1)+(ret<<3)+ch-'0', ch=getchar();
return ret;
}
struct state
{
int o,dis;
inline bool operator <(const state S) const { return dis > S.dis; }
};
queue <int> Q;
priority_queue <state> q;
int n,m,num,cnt,ans;
int f[N],dis[5][N],et[M],ed[M],nx[M],id[5],topo[N],du[N],h[N];
bool vis[N];
struct edge
{
int to,nx,dis;
}e[M];
inline void add(int x,int y,int z)
{
et[++num]=y, ed[num]=z, nx[num]=f[x], f[x]=num;
}
inline void link(int x,int y,int z)
{
e[++cnt]=(edge){y,h[x],z}, h[x]=cnt;
}
inline void dijkstra(int u)
{
state st;
int i,o,to,len,Dis;
for (i=1; i<=n; ++i)
vis[i]=false, dis[u][i]=inf;
o=id[u];
dis[u][o]=0, q.push((state){o,0});
while (!q.empty())
{
st=q.top(), q.pop();
o=st.o, Dis=st.dis;
if (vis[o])
continue;
vis[o]=true;
for (i=f[o]; i; i=nx[i])
{
to=et[i], len=ed[i];
if (dis[u][to] > Dis+len)
dis[u][to]=Dis+len, q.push((state){to,dis[u][to]});
}
}
}
inline void topology()
{
int i,o,to,len;
for (i=1; i<=n; ++i)
if (!du[i])
Q.push(i);
while (!Q.empty())
{
o=Q.front(), Q.pop();
ans=max(ans,topo[o]);
for (i=h[o]; i; i=e[i].nx)
{
to=e[i].to, len=e[i].dis;
topo[to]=max(topo[to],topo[o]+len);
if (!(--du[to]))
Q.push(to);
}
}
}
int main()
{
// freopen("way.in","r",stdin);
// freopen("way.out","w",stdout);
int i,x,y,z,l1,l2;
n=gi(), m=gi();
for (i=1; i<5; ++i)
id[i]=gi();
num=1;
for (i=1; i<=m; ++i)
x=gi(), y=gi(), z=gi(), add(x,y,z), add(y,x,z);
for (i=1; i<5; ++i)
dijkstra(i);
l1=dis[1][id[2]], l2=dis[3][id[4]];
for (x=1; x<=n; ++x)
for (i=f[x]; i; i=nx[i])
{
y=et[i], z=ed[i];
if (dis[1][x]+z+dis[2][y] != l1 || dis[3][x]+z+dis[4][y] != l2)
continue;
link(x,y,z), du[y]++;
}
topology();
for (i=1; i<=n; ++i)
h[i]=topo[i]=0;
for (x=1; x<=n; ++x)
for (i=f[x]; i; i=nx[i])
{
y=et[i], z=ed[i];
if (dis[1][x]+z+dis[2][y] != l1 || dis[3][y]+z+dis[4][x] != l2)
continue;
link(x,y,z), du[y]++;
}
topology();
printf("%d\n",ans);
return 0;
}
「SDOI 2009」Elaxia的路线的更多相关文章
- 「BZOJ 1876」「SDOI 2009」SuperGCD「数论」
题意 求\(\gcd(a, b)\),其中\(a,b\leq10^{10000}\) 题解 使用\(\text{Stein}\)算法,其原理是不断筛除因子\(2\)然后使用更相减损法 如果不筛\(2\ ...
- 「BZOJ 1297」「SCOI 2009」迷路「矩阵乘法」
题意 边权\(w \in [1, 9]\)的\(n\)个结点的有向图,图上从\(1\)到\(n\)长度为\(d\)的路径计数,\(n \leq 10\). 题解 如果边权为\(1\)很经典,设\(f[ ...
- 「SDOI 2018」反回文串
题目大意: 求字符集大小为$k$长度为$n$的经循环移位后为回文串的数量. 题解: 这题是D1里最神的吧 考虑一个长度为$n$回文串,将其循环移位后所有的串都是满足要求的串. 但是显然这样计算会算重. ...
- 「SDOI 2018」战略游戏
题目大意: 给一个$G=(V,E)$,满足$|V|=n$,$|E|=m$,且保证图联通,有Q个询问,每组询问有s个点,求图中有多少点满足:将其删去后,这s个点中存在一对点集$(a,b)$不联通且删去点 ...
- 「BZOJ 1924」「SDOI 2010」所驼门王的宝藏「Tarjan」
题意 一个\(r\times c\)的棋盘,棋盘上有\(n\)个标记点,每个点有三种类型,类型\(1\)可以传送到本行任意标记点,类型\(2\)可以传送到本列任意标记点,类型\(3\)可以传送到周围八 ...
- 「BZOJ 3123」「SDOI 2013」森林「启发式合并」
题意 你有一个森林,你需要支持两个操作 查询两个结点路径上权值第\(k\)小 两个点之间连一条边 强制在线,结点数\(\leq 8\times 10^4\) 题解 如果可以离线,这就是一个主席树板子题 ...
- 「BZOJ 3529」「SDOI 2014」数表「莫比乌斯反演」
题意 有一张 \(n\times m\) 的数表,其第\(i\)行第\(j\)列的数值为能同时整除\(i\)和\(j\)的所有自然数之和. \(T\)组数据,询问对于给定的 \(n,m,a\) , 计 ...
- 「BZOJ 3994」「SDOI 2015」约数个数和「莫比乌斯反演」
题意 设\(d(x)\)为\(x\)的约数个数,求\(\sum_{i=1}^{n}\sum_{j=1}^{m}d(ij)\). 题解 首先证个公式: \[d(ij) = \sum_{x|i}\sum_ ...
- Solution -「SDOI 2018」「洛谷 P4606」战略游戏
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的无向连通图,\(q\) 次询问,每次给出一个点集 \(s\),求至少在原图中删去多 ...
随机推荐
- mysql莫名的主键重复
REPAIR TABLE t_car_type; OPTIMIZE TABLE t_car_type; 可解决问题
- UVA12096 - The SetStack Computer(set + map映射)
UVA12096 - The SetStack Computer(set + map映射) 题目链接 题目大意:有五个动作: push : 把一个空集合{}放到栈顶. dup : 把栈顶的集合取出来, ...
- robotframework使用之 下拉框的选择
选择下拉框有几种方式处理,首先在浏览器F12选择下拉框 1. F12后看见下拉框的源码是<option xxx> <select class="w_60" dat ...
- Splash动画启动app时空白屏
相信大多数人一开始都会对启动app的时候出现先白瓶或者黑屏然后才进入第一个界面,例如:SplashActivity.那这是什么原因造成的呢? <style name="Splash_T ...
- 安装部署Solrcloud
实验说明: 三台虚拟机做solrcloud集群 安装solr前请确保jdk .tomcat.zookeeper已安装好,否则无法启动 三台虚拟机I ...
- 简述什么是ajax、javascript、json、Jquery?
什么是Javascript? 基于对象.解释型.事件驱动.脚本语言.封装在<script>标签中使用.弱类型.与浏览器交互执行 什么 是Ajax? ajax是一种编程模式.在客户端与服务器 ...
- IDEA下使用Jetty进行Debug模式调试
过程例如以下: (1)找到选项卡中的 –Run– 然后找到 –Edit Configurations (2)点击下图中绿色的plus–找到Maven点进去 (3)依照下边的方式在Command lin ...
- IntelliJ IDEA打可执行jar包
<plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <config ...
- Objective-C 内存管理之dealloc方法中变量释放处理
本文转载至 http://blog.sina.com.cn/s/blog_a843a8850101ds8j.html (一).关于nil http://cocoadevcentral.com/d/ ...
- LR中select next row和update value on的设置
LR的参数的取值,和select next row和update value on的设置都有密不可分的关系.下表给出了select next row和update value on不同的设置,对于LR ...