最短路简单建图 floyd算法 & Dijkstra算法 -- Tram POJ - 1847

Tram POJ - 1847

题意:
在一个交通网络上有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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值