标签:
大意:
有一个 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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
Codeforces 238E. Meeting Her 图论+记忆化搜索
标签:
原文地址:http://blog.csdn.net/ck_boss/article/details/46767327