题意:
在一个交通网络上有N个路口, 每个路口指向多个方向, 默认驶向第一个方向, 驶向其他方向时需要进行一次操作, 求从a到b最小的操作数
题解:
直接建图, 默认权值为inf, 开关最开始指向的是第一个,第一个所以权值为0
之后的权值为1
floyd算法:
#include<bits/stdc++.h>
using namespace std;
const int N = 105, INF = 0x3f3f3f3f;
int n, a, b, g[N][N], k, v;
void floyd() {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
}
}
int main() {
memset(g, 0x3f, sizeof(g));
scanf("%d%d%d", &n, &a, &b);
for (int u = 1; u <= n; u++) {
scanf("%d", &k);
for (int j = 1; j <= k; j++) {
scanf("%d", &v);
if (j == 1) g[u][v] = 0;
else g[u][v] = 1;
}
}
floyd();
if (g[a][b] == INF) printf("-1");
else printf("%d", g[a][b]);
return 0;
}
Dijkstra算法:
#include<bits/stdc++.h>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1<<30;
const LL maxn = 110;
int N, s, e, w[maxn][maxn];
int d[maxn];
bool used[maxn];
typedef pair<int, int> P;
void Dijkstra(){
priority_queue<P, vector<P>, greater<P> > q;
fill(d, d+maxn, inf);
q.push(P(d[s]=0, s));
while(!q.empty()){
P cur = q.top();
q.pop();
int u = cur.second;
if(used[u]) continue;
used[u] = true;
for(int v = 1; v <= N; ++v){
if(d[u]+w[u][v] < d[v]){
d[v] = d[u]+w[u][v];
q.push(P(d[v], v));
}
}
}
}
int main()
{
int k, v;
cin >> N >> s >> e;
fill(w[0], w[0]+maxn*maxn, inf);
for(int u = 1; u <= N; ++u){
cin >> k;
for(int j = 1; j <= k; ++j){
cin >> v;
if(j==1) w[u][v] = 0;
else w[u][v] = 1;
}
}
Dijkstra();
if(d[e]<inf) cout << d[e] << endl;
else cout << "-1" << endl;
return 0;
}