http://acm.hdu.edu.cn/showproblem.php?pid=3790
题意:多了一个花费的限制条件,距离相等则选花费少的。
思路:直接在原来的判断条件上加就行,不要想太多。注意有重边。
#include <stdio.h>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
int dis[N], cost[N], G1[N][N], G2[N][N], n;
bool vis[N];
void dijkstra(int s)
{
for(int i = 1; i <= n; i++)
{
dis[i] = INF;
cost[i] = INF;
}
dis[s] = 0;
cost[s] = 0;
for(int i = 1; i <= n; i++)
{
int k = -1;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (k==-1 || dis[j]<dis[k] || (dis[j]==dis[k]&&(cost[j]<cost[k]))))
k = j;
}
if(k == -1) break;
vis[k] = true;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (dis[k]+G1[k][j]<dis[j] || (dis[k]+G1[k][j]==dis[j]&&(cost[k]+G2[k][j]<cost[j]))))
{
dis[j] = dis[k]+G1[k][j];
cost[j] = cost[k]+G2[k][j];
}
}
}
}
void spfa(int s)
{
queue<int>que;
for(int i = 1; i <= n; i++)
{
dis[i] = INF;
cost[i] = INF;
}
dis[s] = 0;
cost[s] = 0;
vis[s] = true;
que.push(s);
while(!que.empty())
{
int now = que.front();
que.pop();
vis[now] = false;
for(int i = 1; i <= n; i++)
{
if(dis[now]+G1[now][i]<dis[i] || (dis[now]+G1[now][i]<dis[i]&&(cost[now]+G2[now][i]<cost[i])))
{
dis[i] = dis[now]+G1[now][i];
cost[i] = cost[now]+G2[now][i];
if(!vis[i])
{
vis[i] = true;
que.push(i);
}
}
}
}
}
int main()
{
// freopen("in.txt", "r", stdin);
int m, u, v, s, t, w1, w2;
while(~scanf("%d%d", &n, &m))
{
if(n == 0 && m == 0) break;
memset(vis, false, sizeof(vis));
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j)
{
G1[i][j] = 0;
G2[i][j] = 0;
}
else
{
G1[i][j] = INF;
G2[i][j] = INF;
}
}
for(int i = 1; i <= m; i++)
{
scanf("%d%d%d%d", &u, &v, &w1, &w2);
if(w1<G1[u][v] || (w1==G1[u][v]&&w2<G2[u][v]))
{
G1[u][v] = G1[v][u] = w1;
G2[u][v] = G2[v][u] = w2;
}
}
scanf("%d%d", &s, &t);
// dijkstra(s);
spfa(s);
printf("%d %d\n", dis[t], cost[t]);
}
return 0;
}