Codeforces gym 101149 L 最短路

Right Build
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

In a MMORPG «Path of Exile» characters grow by acquiring talents for special talent points received in a game process. Talents can depend on others. A talent can be acquired only if a character has at least one of the talents it depends on. Acquiring one talent costs one talent point. At the beginning of the game a character has a single starting talent.

Schoolboy Vasiliy decided to record a video manual how to level-up a character in a proper way, following which makes defeating other players and NPCs very easy. He numbered all  talents as integers from 0 to n, so that the starting talent is numbered as 0. Vasiliy thinks that the only right build is acquiring two different talents a and b as quickly as possible because these talents are imbalanced and much stronger than any others. Vasiliy is lost in thought what minimal number of talent points is sufficient to acquire these talents from the start of the game.

Input

The first line contains four space-separated integers: nma and b (2 ≤ n, m ≤ 2·1051 ≤ a, b ≤ na ≠ b) — the total number of talents, excluding the starting talent, the number of dependencies between talents, and the numbers of talents that must be acquired.

Each of the next m lines contains two space-separated integers: xj and yj (0 ≤ xj ≤ n1 ≤ yj ≤ nxj ≠ yj), which means the talent yjdepends on the talent xj. It's guaranteed that it's possible to acquire all  talents given the infinite number of talent points.

Output

Output a single integer — the minimal number of talent points sufficient to acquire talents a and b.

Examples
input
6 8 4 6
0 1
0 2
1 2
1 5
2 3
2 4
3 6
5 6
output
4
input
4 6 3 4
0 1
0 2
1 3
2 4
3 4
4 3
output
3


题意:有n个技能  m个条件  接下来是两个终极技能的编号

m个条件是  x y  代表必须y的前置技能是x

只要学会任意一个前置技能就能学当前技能

问把两个终极技能学了至少要学多少前置技能


题解:先用第一个终极技能跑一个最短路  再用第二个跑最短路

枚举他们两个的交点  然后去min即可


#include
#include
#include
#include
#include
using namespace std;
const int maxn=211111;
struct renode{
	int to,nxt;
}reed[maxn<<1];
int rehead[maxn];
struct node{
	int to,nxt;
}ed[maxn<<1];
int head[maxn],cnt;
void addedge(int u,int v){
	ed[cnt].to=v;
	ed[cnt].nxt=head[u];
	reed[cnt].to=u;
	reed[cnt].nxt=rehead[v];
	head[u]=rehead[v]=cnt;
	cnt++;
}
int dis[maxn],disa[maxn],disb[maxn];
queueq;
int main()
{
	int n,m,a,b;
	memset(head,-1,sizeof(head));
	memset(rehead,-1,sizeof(head));
	memset(dis,-1,sizeof(head));
	memset(disa,-1,sizeof(disa));
	memset(disb,-1,sizeof(disb));
	scanf("%d%d%d%d",&n,&m,&a,&b);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v);
	}
	dis[0]=0;
	q.push(0);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=head[u];~i;i=ed[i].nxt){
			int v=ed[i].to;
			if(dis[v]==-1){
				dis[v]=dis[u]+1;
				q.push(v);
			}
		}
	}
	disa[a]=0;
	q.push(a);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=rehead[u];~i;i=reed[i].nxt){
			int v=reed[i].to;
			if(disa[v]==-1){
				disa[v]=disa[u]+1;
				q.push(v);
			}
		}
	}
	disb[b]=0;
	q.push(b);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=rehead[u];~i;i=reed[i].nxt){
			int v=reed[i].to;
			if(disb[v]==-1){
				disb[v]=disb[u]+1;
				q.push(v);
			}
		}
	}
	int ans=-1;
	for(int i=0;i<=n;i++){
		int step;
		if(dis[i]==-1||disa[i]==-1||disb[i]==-1)continue;
		step=disb[i]+disa[i]+dis[i];
		if(ans==-1||step


你可能感兴趣的:(最短路)