题目
题意: 给定m个路线,n个点。m个路线是说,某条路线上左边的点可以花0的代价到达右边的点。但是从某条路线换到另一条路线就要花费1的代价。
思路: 用最笨的方法,建图。建图是mn2/2的。同一条路线上的花费为1.
最后结果为dist[n] - 1.因为第一次是不换乘的,从第二次开始就换乘了。
时间复杂度: O(mnn)
代码:
// Problem: 最优乘车
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/922/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N = 502;
const int INF = 0x3f3f3f3f;
int a[N][N];
int n,m,k,T;
#define fir(i,a,b) for(int i=a;i<=b;++i)
int dist[N];
bool vis[N];
void bfs(int S)
{
memset(dist,0x3f,sizeof(dist));
dist[S] = 0;
queue<int> q;
q.push(S);
while(q.size())
{
int u = q.front(); q.pop();
for(int i=1;i<=n;++i)
{
if(i==u) continue;
if(a[u][i]==1 && dist[i] == INF)
{
dist[i] = dist[u] + 1;
q.push(i);
}
}
}
}
void solve()
{
cin>>m>>n;
fir(i,1,n)
fir(j,1,n)
{
if(i==j) a[i][j] = 0;
else a[i][j] = 0x3f3f3f3f;
}
for(int i=0;i<m;++i)
{
vector<int> vv;
int x; char ch;
while(scanf("%d%c",&x,&ch)!=EOF)
{
vv.push_back(x);
if(ch == '\n') break;
}
for(int j=0;j<vv.size();++j)
{
for(int k=j+1;k<vv.size();++k)
{
int l = vv[j],r = vv[k];
a[l][r] = 1;
}
}
}
bfs(1);
if(dist[n] == 0x3f3f3f3f) dist[n] = 0;
cout<<dist[n]-1;
}
signed main(void)
{
// ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}