原题链接: ​​ http://acm.hdu.edu.cn/showproblem.php?pid=3790​


一:原题内容


Problem Description


给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。


 


Input


输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)


 


Output


输出 一行有两个数, 最短距离及其花费。


 


Sample Input


3 2
1 2 5 6
2 3 4 5
1 3
0 0



Sample Output


9 11


二:分析理解

这题很恶心!需要对输入的数据处理一下。不然不对,也就是输入的数据可能是这样的:

3 2
1 2 5 6
1 2 5 5
1 2

注意红色部分,这样的数据你需要处理一下,一开始直接没想到这个问题,,尿了!

三:AC代码

#include<iostream>  
#include<string.h>
#include<algorithm>

using namespace std;

struct Node
{
int b;
int p;
};


int n, m;
int a, d, b, p;
int s, t;
Node node[1005][1005];
int dis[1005];
int cost[1005];
bool visited[1005];

int main()
{
while (scanf("%d%d", &n, &m) && (n || m))
{
memset(node, 0, sizeof(node));
memset(dis, 0, sizeof(dis));
memset(cost, 0, sizeof(cost));
memset(visited, 0, sizeof(visited));

for (int i = 0; i < m; i++)
{
scanf("%d%d%d%d", &a, &d, &b, &p);

if (node[a][d].b == 0 || b < node[a][d].b)
{
node[a][d].b = node[d][a].b = b;
node[a][d].p = node[d][a].p = p;
}
else if(b==node[a][d].b&&p<node[a][d].p)
node[a][d].p = node[d][a].p = p;
}

scanf("%d%d", &s, &t);

for (int i = 1; i <= n; i++)
{
if (i != s&&node[s][i].b != 0)
{
dis[i] = node[s][i].b;
cost[i] = node[s][i].p;
}
else
{
dis[i] = INT_MAX;
cost[i] = 99999999;
}
}

dis[s] = 0;
cost[s] = 0;
visited[s] = true;

for (int i = 1; i <= n - 1; i++)
{
int min = INT_MAX;
int minPos;
int cos;
for (int j = 1; j <= n; j++)
{
if (!visited[j] && dis[j] < min)
{
min = dis[j];
minPos = j;
cos = cost[j];
}
}

visited[minPos] = true;

for (int k = 1; k <= n; k++)
{
if (!visited[k] && node[minPos][k].b != 0)
{
if (node[minPos][k].b + min < dis[k])
{
dis[k] = node[minPos][k].b + min;
cost[k] = node[minPos][k].p + cos;
}
else if (node[minPos][k].b + min == dis[k])
{
if (node[minPos][k].p + cos < cost[k])
cost[k] = node[minPos][k].p + cos;
}
}
}

}

printf("%d %d\n", dis[t], cost[t]);
}

return 0;
}