大意:
有一个 n 个结点的有向图,边权均为 1。Urapl 想从 a 出发去 b。有 p 个公交车公司。在每
一秒的开始,第 i 个公司的公交车随机选择一条从 s i 到 t i 的最短路径然后走这条路径。如果
一个公交车经过 Urpal 所在的交叉点,则 Urpal 可以上这辆公交车,他可以在中途任意一个结
点下车。
在任何时刻 Urpal 只知道他自己的位置和约会地点。当他上了公交车时他只知道这辆公交
车属于第几个公司。当然 Urpal 知道城市地图和每个公司的 (s i , t i )。
求最坏情况下他需要乘坐公交车的次数。
解法:
先求出每辆公交车必须经过的点,再对必须经过的点搜索,算出每个点到目的地最坏情况下还要转几次车
/* ***********************************************
Author :CKboss
Created Time :2015年07月05日 星期日 22时53分11秒
File Name :CF238E_2.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn=110;
const int INF=0x3f3f3f3f;
int n,m,a,b,t;
int from[maxn],to[maxn];
int dist[maxn][maxn];
int incur[maxn][maxn];
bool vis[maxn];
int g[maxn],f[maxn];
int dfs(int cur,int aim)
{
if(cur==aim) return f[cur];
if(vis[cur]==true) return g[cur];
vis[cur]=true; g[cur]=0;
for(int i=1;i<=n;i++)
{
if(dist[cur][i]+dist[i][aim]==dist[cur][aim]
&&dist[cur][aim]==dist[i][aim]+1)
g[cur]=max(g[cur],dfs(i,aim));
}
return g[cur]=min(g[cur],f[cur]);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d%d%d%d",&n,&m,&a,&b);
memset(dist,63,sizeof(dist));
for(int i=1;i<=n;i++) dist[i][i]=0;
for(int i=0,u,v;i<m;i++)
{
scanf("%d%d",&u,&v);
dist[u][v]=1;
}
/// floyd
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
/// get incur
scanf("%d",&t);
for(int k=0;k<t;k++)
{
scanf("%d%d",from+k,to+k);
int S=from[k],T=to[k];
if(dist[S][T]==INF) continue;
for(int i=1;i<=n;i++)
{
if(dist[S][i]+dist[i][T]==dist[S][T])
{
/// check i
bool flag=true;
for(int j=1;j<=n&&flag;j++)
{
if(j==i) continue;
if(dist[S][j]+dist[j][T]==dist[S][T])
{
if(dist[S][j]==dist[S][i])
flag=false;
}
}
if(flag==true) incur[k][i]=1;
}
}
}
memset(f,63,sizeof(f)); f[b]=0;
while(true)
{
bool gono=false;
for(int i=0;i<t;i++)
{
if(dist[from[i]][to[i]]==INF) continue;
memset(vis,0,sizeof(vis));
for(int j=1;j<=n;j++)
{
if(incur[i][j])
{
int temp=dfs(j,to[i])+1;
if(temp<f[j])
{
f[j]=temp; gono=true;
}
}
}
}
if(gono==false) break;
}
int ans=f[a];
if(ans>=INF) ans=-1;
printf("%d\n",ans);
return 0;
}