题意:给你一个有向图,多次询问从一个点到另一个点字典序最小的路径上第k个点。

考虑枚举每一个点作为汇点(记为i),计算出其他所有点到i的字典序最小的路径。(当然,枚举源点也是可行的)

首先,我们建一张反向图,从i开始dfs,以删去所有无法到达i的点。

然后,因为此时图上所有点都可以到达i,所以可以贪心地在从每一个点出发的边中只保留终点编号最小的边,而把其他边删除。

这样就可以保证路径是字典序最小的,并且从每个点到i的路径只有一条。

而题目中给出了这样一种情况:

  • there are paths from sj to tj, but for every such path p there is another path q from sj to tj, such that pi > qi, where i is the minimum integer for which pi ≠ qi.

因此最后可能某些未被删去的点无法到达i,就需要从i开始再dfs一遍,以删去这些点。

在最后这次dfs的同时通过倍增记录路径(即祖先节点),以实现O(logn)地查询路径的第k个点。

时间复杂度O(n^2*logn+q*logn)。

 #include <bits/stdc++.h>
#define travel(i,x,p) for(int i=p.fir[(x)];i;i=p.con[i].la)
#define nex(x,p) p.con[x].b
using namespace std;
const int N=,Q=;
struct edge{
int la,b;
};
struct graph{
edge con[N];
int tot,fir[N];
bool vis[N];
void init()
{
tot=;
memset(fir,,sizeof fir);
}
void add(int from,int to)
{
con[++tot].la=fir[from];
con[tot].b=to;
fir[from]=tot;
}
void dfs(int pos)
{
vis[pos]=;
for(int i=fir[pos];i;i=con[i].la)
{
if(!vis[con[i].b]) dfs(con[i].b);
}
}
}p1,p2,p3;
int n,m,q,anc[N][];
struct query{
int s,k,id;
};
vector<query>ask[N];
int ans[Q];
void exdfs(int pos)
{
p3.vis[pos]=;
for(int i=;i<=;i++)
anc[pos][i]=anc[anc[pos][i-]][i-];
for(int i=p3.fir[pos];i;i=p3.con[i].la)
{
anc[p3.con[i].b][]=pos;
exdfs(p3.con[i].b);
}
}
void doit(query tmp,int pos)
{
if(!p3.vis[tmp.s]) ans[tmp.id]=-;
else
{
tmp.k--;
pos=tmp.s;
for(int i=;i>=;i--)
{
if((<<i)<=tmp.k)
tmp.k-=(<<i),pos=anc[pos][i];
}
if(pos==) ans[tmp.id]=-;
else ans[tmp.id]=pos;
}
}
void solve(int pos)
{
memset(p2.vis,,sizeof p2.vis);
p2.dfs(pos);
p3.init();
int tmp;
for(int i=;i<=n;i++)
{
if(p2.vis[i]&&i!=pos)
{
tmp=n+;
travel(j,i,p1)
{
if(p2.vis[nex(j,p1)]&&nex(j,p1)<tmp)
tmp=nex(j,p1);
}
if(tmp!=n+) p3.add(tmp,i);
}
}
memset(p3.vis,,sizeof p3.vis);
memset(anc,,sizeof(anc));
exdfs(pos);
for(int i=;i<(int)ask[pos].size();i++)
{
doit(ask[pos][i],pos);
}
}
int main()
{
int from,to;
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=m;i++)
{
scanf("%d%d",&from,&to);
p1.add(from,to);
p2.add(to,from);
}
int x,y,k;
for(int i=;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&k);
ask[y].push_back((query){x,k,i});
}
for(int i=;i<=n;i++)
solve(i);
for(int i=;i<=q;i++)
printf("%d\n",ans[i]);
return ;
}

小结:在诸如最小字典序路径和其他问题中,可以通过预处理以保证贪心的正确性。

【做题】Codeforces Round #436 (Div. 2) F. Cities Excursions——图论+dfs的更多相关文章

  1. Codeforces Round #436 (Div. 2)【A、B、C、D、E】

    Codeforces Round #436 (Div. 2) 敲出一身冷汗...感觉自己宛如智障:( codeforces 864 A. Fair Game[水] 题意:已知n为偶数,有n张卡片,每张 ...

  2. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  3. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  4. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  5. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  6. 水题 Codeforces Round #308 (Div. 2) A. Vanya and Table

    题目传送门 /* 水题:读懂题目就能做 */ #include <cstdio> #include <iostream> #include <algorithm> ...

  7. 水题 Codeforces Round #105 (Div. 2) B. Escape

    题目传送门 /* 水题:这题唯一要注意的是要用double,princess可能在一个小时之内被dragon赶上 */ #include <cstdio> #include <alg ...

  8. 水题 Codeforces Round #302 (Div. 2) A Set of Strings

    题目传送门 /* 题意:一个字符串分割成k段,每段开头字母不相同 水题:记录每个字母出现的次数,每一次分割把首字母的次数降为0,最后一段直接全部输出 */ #include <cstdio> ...

  9. 水题 Codeforces Round #299 (Div. 2) A. Tavas and Nafas

    题目传送门 /* 很简单的水题,晚上累了,刷刷水题开心一下:) */ #include <bits/stdc++.h> using namespace std; ][] = {" ...

随机推荐

  1. UVa437 The Tower of Babylon(巴比伦塔)

    题目 有n(n<=30)种立方体,每种有无穷多个,摞成尽量高的柱子,要求上面的立方体要严格小于下面的立方体. 原题链接 分析 顶面的大小会影响后续的决策,但不能直接用d[a][b]来表示,因为可 ...

  2. 找不到System.Web.Optimization命名空间

    找不到System.Web.Optimization命名空间,无法完成BundleConfig.cs内容的添加. 解决方法如下:打开程序包管理控制台,在控制台中输入:Install-PackageMi ...

  3. 【转】robot framework + python实现http接口自动化测试框架

    前言 下周即将展开一个http接口测试的需求,刚刚完成的java类接口测试工作中,由于之前犯懒,没有提前搭建好自动化回归测试框架,以至于后期rd每修改一个bug,经常导致之前没有问题的case又产生了 ...

  4. Python -- 连接数据库SqlServer

    用Python几行代码查询数据库,此处以Sql server为例. 1. 安装pymssql,在cmd中运行一下代码 pip install pymssql 2. 链接并执行sql语句 #-*-cod ...

  5. django migrate无效的解决方法

    遇到一个很奇怪的问题 python manage.py makemigrations 的时候显示要创建两张表,但是执行 python manage.py migrate 的时候不能识别,也就是说失效了 ...

  6. [DeploymentService:290066]Error occurred while downloading files from admin server for deployment request "0". Underlying error is: "null"

    weblogic 莫名无法启动: <Apr , :: PM CST> <Error> <Deployer> <BEA-> <Failed to i ...

  7. Collections集合工具类的方法

    addAll & shuffle: 返回类型为boolean类型,执行完操作不接收也行: 其中,静态方法,与对象无关,类名点方法名直接调用: 点点点为可变参数,随便填写几个参数都可以: sor ...

  8. javaweb笔记06—(页面跳转及编码格式)

    1.指令:<%@     %>:一个页面可以有多个import, 但是标识本页面为jsp页面的指令只能是一条(建议是一条 ) 2.出错页面:<%@ isError(true)%> ...

  9. js 显示刚刚上传的图片 (onchange事件)

    <table> <tr width="100"> <td>上传商场图片:</td> <td> <input typ ...

  10. linux shell习题

    课件地址:https://wenku.baidu.com/view/bac2ff10f18583d0496459f3.html 1.测试环境变量:HOME,PWD,IFS等2.测试位置变量:$$,$# ...