题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3790
相比HDU1874,此题在选择道路的条件更为苛刻一些,其他基本类同。问题就是这题如果用cin的话,会无限超时的,我就被这个坑惨了,改用scanf就没事了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 1005;
const int Max = 0x7fffffff;//此值大小会影响答案的判断
int length[MAX][MAX], cost[MAX][MAX];
int dist[MAX], pay[MAX];
bool visit[MAX];
int mindist, minpay, n, m;
void path()//<span style="font-family: Arial, Helvetica, sans-serif;">Dijkstra算法</span>
{
for(int i = 2; i <= n; i++)
{
mindist = Max;
minpay = Max;
int k;
for(int j = 1; j <= n; j++)
{
if(mindist > dist[j] && !visit[j])
{
mindist = dist[j];
minpay = pay[j];
k = j;
}
else if(mindist == dist[j] && minpay > pay[j] && !visit[j])
{
mindist = dist[j];
minpay = pay[j];
k = j;
}
}
visit[k] = true;
for(int j = 1; j <= n; j++)
{
//dist[j] = min(dist[j], dist[k]+length[k][j]);
//pay[j] = min(pay[j], pay[k]+cost[k][j]);
if(!visit[j] && (length[k][j] < Max))更新是要一起更新,要不然就可能变成两条路
{
if(dist[k] + length[k][j] < dist[j])
{
dist[j] = dist[k] + length[k][j];
pay[j] = pay[k] + cost[k][j];
}
else if(dist[j] == dist[k] + length[k][j] && pay[j] > pay[k] + cost[k][j])
pay[j] = pay[k] + cost[k][j];
}
}
}
return ;
}
int main()
{
while(scanf("%d%d", &n , &m), n||m)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j)
{
length[i][j] = 0;
cost[i][j] = 0;
}
else
{
length[i][j] = Max;
cost[i][j] = Max;
}
}
for(int i = 1; i <= m; i++)
{
int p1, p2, len, c;
scanf("%d%d%d%d", &p1, &p2, &len, &c);
if(length[p1][p2] > len)
{
length[p1][p2] = length[p2][p1] = len;
cost[p1][p2] = cost[p2][p1] = c;
}
else if(length[p1][p2] == len && cost[p1][p2] > c)
cost[p1][p2] = cost[p2][p1] = c;
}
int start, fin;
scanf("%d%d", &start, &fin);
memset(visit, false, sizeof(visit));
for(int i = 1; i <= n; i++)
{
dist[i] = length[start][i];
pay[i] = cost[start][i];
}
visit[start] = true;
path();
printf("%d %d\n", dist[fin], pay[fin]);
}
return 0;
}