1111 Online Map(30分)

文章讲述了如何使用Dijkstra算法和深度优先搜索(DFS)解决两点之间的最短路径问题,同时提到DFS在处理最后一个测试点时可能会超时。代码展示了如何在C++中实现这两种方法并处理双向边和单向边的情况。
摘要由CSDN通过智能技术生成

题目翻译:

就是求解一个点到另一个点的最短路径。

不过由于限制条件很多,还得分开求两次,所以写起来就很繁。

题解思路:

可以用dijkstra或者dfs,用后者的话最后一个测试点可能会超时。

代码:

dfs(最后一个测试点超时):

#include<bits/stdc++.h>
using namespace std;
int N, M;//结点数量,边的数量
vector<int> v[501];
int dis[501][501];
int cost[501][501];
int mindis[501];
int min_len = INT_MAX, min_cost = INT_MAX;
vector<int> path1, path2, temp;
int so, des;
int temp_cost = INT_MAX;

void dfs(int curnode, int curlen,int curcost)
{
	if (curlen > mindis[curnode]) return;
	else
		mindis[curnode] = curlen;
	temp.push_back(curnode);
	if (curnode == des)
	{
		if (curlen < min_len)
		{
			min_len = curlen;
			path1 = temp;
			temp_cost = curcost;
		}
		if (curlen == min_len&&curcost<temp_cost)
			path1 = temp;
	}
	else {
		for (auto i : v[curnode])
			dfs(i, curlen + dis[curnode][i], curcost + cost[curnode][i]);
	}
	temp.pop_back();
}

void dfs2(int curnode, int curlen)
{
	if (curlen > mindis[curnode]) return;
	else
		mindis[curnode] = curlen;
	temp.push_back(curnode);
	if (curnode == des)
	{
		if (curlen < min_cost)
		{
			min_cost = curlen;
			path2 = temp;
		}
		if (curlen == min_cost && temp.size() < path2.size())
			path2 = temp;
	}
	else {
		for (auto i : v[curnode])
			dfs2(i, curlen + cost[curnode][i]);
	}
	temp.pop_back();
}

int main()
{
	cin >> N >> M;
	int q, w, e, r, t;
	for (int i = 0;i < M;i++)
	{
		cin >> q >> w >> e >> r >> t;
		if (e)//单向
		{
			v[q].push_back(w);
			dis[q][w] = r;
			cost[q][w] = t;
		}
		else//双向
		{
			v[q].push_back(w);
			v[w].push_back(q);
			dis[q][w] = dis[w][q] = r;
			cost[q][w] = cost[w][q] = t;
		}
	}
	for (int i = 0;i < 501;i++)
		mindis[i] = INT_MAX;
	cin >> so >> des;
	dfs(so, 0, 0);
	for (int i = 0;i < 501;i++)
		mindis[i] = INT_MAX;
	temp.clear();
	dfs2(so, 0);
	if (path1 != path2)
	{
		cout << "Distance = " << min_len << ":";
		for (int i = 0;i < path1.size();i++)
		{
			if (i)
				cout << " ->";
			cout << " " << path1[i];
		}
		cout << endl;
	}
	else
		cout << "Distance = " << min_len << "; ";
	cout << "Time = " << min_cost << ":";
	for (int i = 0;i < path2.size();i++)
	{
		if (i)
			cout << " ->";
		cout << " " << path2[i];
	}
}

dijkstra(AC,转载于AC代码 )

#include<bits/stdc++.h>
using namespace std;

int n, m, source, dest, min_distance, min_time;
vector<int> ans_t, ans_d, dpre(500, -1), tpre(500, -1);
vector<vector<int>> times(500, vector<int>(500, -1)), distances(500, vector<int>(500, -1)), graph(500,vector<int>(500, 0));
void dfs1(int x){
    if(x == -1) return;
    dfs1(dpre[x]);
    ans_d.push_back(x);
}
void dfs2(int x){
    if(x == -1) return;
    dfs2(tpre[x]);
    ans_t.push_back(x);
}
void dijkstra1(int beg){
    vector<int> lowcost(500, 0x3f3f3f3f), vis(500, 0), dtime(500, 0x3f3f3f3f);
    lowcost[beg] = 0;
    dpre[beg] = -1;
    for (int i = 0; i < n;i++){
        int Min = 0x3f3f3f3f, k = -1;
        for (int j = 0; j < n;j++){
            if(vis[j] == 0 && lowcost[j] < Min){
                Min = lowcost[j];
                k = j;
            }
        }
        if(k == -1) break;
        vis[k] = 1;
        for (int j = 0; j < n;j++){
            if(vis[j] == 0 && graph[j][k] == 1){
                //如果满足条件则更新信息,这里要注意逻辑短路现象
                if(lowcost[j] > lowcost[k] + distances[j][k] || (lowcost[j] == lowcost[k] + distances[j][k] && dtime[k] + times[k][j] < dtime[j])){
                    dpre[j] = k;
                    dtime[j] = dtime[k] + times[k][j];
                    lowcost[j] = lowcost[k] + distances[j][k];
                }
            }
        }
    }
    min_distance = lowcost[dest];
    dfs1(dest);
}

void dijkstra2(int beg){
    vector<int> lowcost(500, 0x3f3f3f3f), vis(500, 0), intersections(500, 0x3f3f3f3f);
    lowcost[beg] = 0;
    tpre[beg] = -1;
    for (int i = 0; i < n;i++){
        int Min = 0x3f3f3f3f, k = -1;
        for (int j = 0; j < n;j++){
            if(vis[j] == 0 && lowcost[j] < Min){
                Min = lowcost[j];
                k = j;
            }
        }
        if(k == -1) break;
        vis[k] = 1;
        for (int j = 0; j < n;j++){
            if(vis[j] == 0 && graph[j][k] == 1){
                if(lowcost[j] > lowcost[k] + times[j][k] || (lowcost[j] == lowcost[k] + times[j][k] && intersections[k] + 1 < intersections[j])){
                    tpre[j] = k;
                    intersections[j] = intersections[k] + 1;
                    lowcost[j] = lowcost[k] + times[j][k];
                }
            }
        }
    }
    min_time = lowcost[dest];
    dfs2(dest);
}

int main(){
    int s, e, a, l, t, isSame = 1;
    cin >> n >> m;
    for (int i = 0; i < m;i++){
        cin >> s >> e >> a >> l >> t;
        graph[s][e] = graph[e][s] = 1;
        times[s][e] = times[e][s] = t;
        distances[s][e] = distances[e][s] = l;
    }
    cin >> source >> dest;
    dijkstra1(source);
    dijkstra2(source);
    if(ans_d.size() == ans_t.size()){
        for (int i = 0; i < ans_t.size();i++){
            if(ans_t[i] != ans_d[i]){
                isSame = 0;
                break;//能省点时间就省点
            }
        }
    }else
        isSame = 0;
    if(isSame == 0){
        printf("Distance = %d: %d", min_distance, ans_d[0]);
        for (int i = 1; i < ans_d.size();i++)
            printf(" -> %d", ans_d[i]);
        printf("\nTime = %d: %d", min_time, ans_t[0]);
        for (int i = 1; i < ans_t.size();i++)
            printf(" -> %d", ans_t[i]);
    }else{
        printf("Distance = %d; Time = %d: %d", min_distance, min_time, ans_t[0]);
        for (int i = 1; i < ans_t.size();i++)
            printf(" -> %d", ans_t[i]);
    }
    cout << endl;
    return 0;
}

坑点:

测试点4用dfs可能会超时

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值