标签:
大意:
有一个 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