ACM 系列 HDU3790

emmmm 一道水题……

但是我卡了……

一直检查,结果卡在输入上

如果出现重复的边而且后者的weight更大的时候就会覆盖掉前面的边……答案就会不正确,price也是同理……

题目没有任何提示……看了别人的代码才发现的

接下来打算继续优化算法

#include <cstdio>
#include <cstring>
#define MAXN 1010
#define Inf 2e9

int dis[MAXN]; //dis数组保存起点到各点的最短距离
int pri[MAXN]; //保存最短费用
int map[MAXN][MAXN]; //保存图的所有边
int p[MAXN][MAXN]; //保存花费
bool vis[MAXN];
int edgeNum, vertex;//保存边的条数和顶点个数

void init() {
	memset(vis, 0, sizeof(vis));
	int i, j;
	for (i = 0; i < MAXN; i++) {
		dis[i] = Inf;
		for (int j = 0; j < MAXN; j++) {
			if (i == j)map[i][j] = 0;
			else {
				map[i][j] = Inf;
			}
		}
	}
}
void input() {
	//cin >> vertex >> edgeNum; //边的条数 和 节点个数
	int start, end, weight, price;
	int num = edgeNum;
	while (num--) {
		scanf("%d %d %d %d", &start, &end, &weight, &price);
                //问题在这里……因为可能有重复的边的情况……emmmmmm
		//cin >> start >> end >> weight >> price;
		if (weight < map[start][end]) {
			map[start][end] = map[end][start] = weight;
			p[start][end] = p[end][start] = price;
		}
		else if (weight == map[start][end]) {
			if (price < map[start][end]) {
				//map[start][end] = map[end][start] = weight;
				p[start][end] = p[end][start] = price;
			}
		}
	}
	
}

void Dijkstra(int s) {

	for (int i = 1; i <= vertex; i++) {
		dis[i] = map[s][i];
		pri[i] = p[s][i];
	}

	vis[s] = true;
	dis[s] = 0;
	pri[s] = 0;

	for (int i = 1; i <= vertex - 1; i++) {
		
		int min = Inf;
		int k = 0;

		for (int j = 1; j <= vertex; j++) {
			//查找 未被访问过的 且距离原点最近的点
			if (!vis[j] && min > dis[j]) {
				min = dis[j];
				k = j;
			}
		}

		//已经访问过原图的所有连通子图后 退出
		if (k == 0) {
			return;
		}

		vis[k] = true;

		for (int j = 1; j <= vertex; j++) {
			if (dis[k] < Inf && map[k][j] < Inf) {
				if (dis[j] > dis[k] + map[k][j]) {

					dis[j] = dis[k] + map[k][j];
					pri[j] = pri[k] + p[k][j];

				}
				else if (dis[j] == dis[k] + map[k][j] && pri[j] > pri[k] + p[k][j]) {

					pri[j] = pri[k] + p[k][j];

				}
			}
		}
	}
}

int main()
{
	//vertex和edgeNum不全为0
	while (scanf("%d %d",&vertex,&edgeNum) && (vertex + edgeNum)) {
		//初始化
		init();
		//输入图的无向边并存储
		input();
		int start, end;
		scanf("%d %d", &start, &end);
		
		Dijkstra(start);
	
		printf("%d %d\n", dis[end],pri[end]);
	}

    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值