『图的遍历与判环』CF864F Cities Excursions

P r o b l e m \mathrm{Problem} Problem

There are n n n cities in Berland. Some pairs of them are connected with m m m directed roads. One can use only these roads to move from one city to another. There are no roads that connect a city to itself. For each pair of cities ( x , y ) (x,y) (x,y) there is at most one road from x x x to y y y .

A path from city s s s to city t t t is a sequence of cities p 1 p_{1} p1 , p 2 p_{2} p2 , … , p k p_{k} pk , where p 1 = s p_{1}=s p1=s , p k = t p_{k}=t pk=t , and there is a road from city p i p_{i} pi to city p i + 1 p_{i+1} pi+1 for each $ i $ from 1 1 1 to k − 1 k-1 k1 . The path can pass multiple times through each city except t t t . It can't pass through t t t more than once.

A path p p p from s s s to t t t is ideal if it is the lexicographically minimal such path. In other words, p p p is ideal path from s s s to t t t if for any other path q q q from s s s to t t t p i p_{i} pi< q i q_{i} qi , where i i i s the minimum integer such that p i ≠ q i p_{i}≠q_{i} pi=qi .

There is a tourist agency in the country that offers q q q unusual excursions: the j j j -th excursion starts at city s j s_{j} sj and ends in city t j t_{j} tj .

For each pair s j s_{j} sj , t j t_{j} tj help the agency to study the ideal path from s j s_{j} sj to t j t_{j} tj . Note that it is possible that there is no ideal path from s j s_{j} sj to t j t_{j} tj . This is possible due to two reasons:

  • there is no path from s j s_{j} sj to t j t_{j} tj ;
  • there are paths from s j s_{j} sj to t j t_{j} tj , but for every such path p p p there is another path q q q from s j s_{j} sj to t j t_{j} tj , such that p i p_{i} pi> q i q_{i} qi , where i i i is the minimum integer for which p i ≠ q i p_{i}≠q_{i} pi=qi .

The agency would like to know for the ideal path from s j s_{j} sj to t j t_{j} tj the k j k_{j} kj -th city in that path (on the way from s j s_{j} sj to t j t_{j} tj ).

For each triple s j s_{j} sj , t j t_{j} tj , k j k_{j} kj ( i ≤ j ≤ k i\le j\le k ijk ) find if there is an ideal path from s j s_{j} sj to t j t_{j} tj and print the k j k_{j} kj -th city in that path, if there is any.


T r a n s l a t e \mathrm{Translate} Translate

给定一个有向图,询问由 s s s t t t的字典序最小的路径的第 k k k个点

若字典序最小的路径构成环输出 − 1 -1 1.


S o l u t i o n \mathrm{Solution} Solution

这道题的思路还是很直白的:

  • 我们将某一个点所连接点的标号排序,那么就转化为了图的遍历。
  • 每次走到某一个点时,统计起点到该点的路径,那么对于询问 ( s , t , k ) (s,t,k) (s,t,k),只要满足统计路径上点的数量大于等于 k k k,且当前点不是从上出来的,那么路径上的第 k k k个点就是合法的答案。

那么接下来就是如何实现的问题反正我是写不来

  • 对于某一个已经遍历过的节点,若第二题遍历到它字典序一定不是最小的,因此我们需要每一个节点都遍历一个。
  • 如果遇到的某一个点处在已经统计过的节点中,那么我们是环上的哪一个根据固定的路径走,都是从环上出来的,肯定无解。因此,我们要在已经统计过的点打上标记,直到从这个点离开以后才能撤销标记。(说明已经不存在环上的路径了)
  • 怎么这么妙啊啊啊啊

C o d e \mathrm{Code} Code

#include 

using namespace std;
const int N = 3010;

int n, m, Q, loop;
int tag[N], cnt[N], ans[N*N];
vector < int > a[N], Now;
vector < pair<int,int> > q[N][N];

int read(void)
{
	int s = 0; char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	while (c >= '0' && c <= '9') s = s * 10 + c - 48, c = getchar();
	return s; 
}

void Dfs(int root, int x)
{
	tag[x] = x * 2 - 1;
	Now.push_back(x);
	for (int i=0;i<q[root][x].size();++i)
	{
		int k = q[root][x][i].first;
		int id = q[root][x][i].second;
		if (k <= Now.size() and loop == 0) 
			ans[id] = Now[k-1]; 
	}
	for (int i=0;i<a[x].size();++i)
	{
		int y = a[x][i];
		if (tag[y] < 2 * y - 1) Dfs(root, y);
		else if (tag[y] == 2 * y - 1) loop ++, cnt[y] ++;
	} 
	Now.pop_back();
	loop -= cnt[x];
	cnt[x] = 0;
	tag[x] = x * 2;
	return;
}

int main(void)
{
	n = read(), m = read(), Q = read();
	for (int i=1;i<=m;++i)
	{
		int x = read(), y = read();
		a[x].push_back(y);
	}
	for (int i=1;i<=n;++i)
		sort(a[i].begin(), a[i].end());
	for (int i=1;i<=Q;++i)
	{
		int x = read(), y = read(), k = read();
		q[x][y].push_back({k, i});
		ans[i] = -1;
	}
	for (int i=1;i<=n;++i)
	{
		loop = 0;
		memset(tag, 0, sizeof tag);
		Dfs(i, i);
	} 
	for (int i=1;i<=Q;++i) printf("%d ", ans[i]);
	return 0;
} 

你可能感兴趣的:(『图的遍历与判环』CF864F Cities Excursions)