小记:这题其实是比较水的,之所以没把它算出水题,是我个人问题,竟然忘记输入判重了,然后就一直wa,唉~
思路:spfa求最短路径,其中入队条件更改下,最短路添加个可以等于,当等于的时候再看花费,如果小于之前的花费就更新之,再将其入队。否则继续。
然后就是输入判重,不然就会wa的。
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define REP(a,b,c) for(int a = b; a < c; ++a)
#define eps 10e-8
const int MAX_ = 1010;
const int N = 100010;
const int INF = 0x7fffffff;
int n;
struct node{
int p, v;
}g[MAX_][MAX_], d[MAX_];
bool vis[MAX_];
int m, cnt;
void spfa(int start)
{
queue<int > q;
REP(i, 0, n+1){
vis[i] = 0;
d[i].p = INF;
d[i].v = INF;
}
vis[start] = 1;
d[start].p = 0;
d[start].v = 0;
q.push(start);
while(!q.empty()){
int cur = q.front(); q.pop();
vis[cur] = 0;
REP(i, 1, n+1){
if(g[cur][i].v != -1 && g[cur][i].p != -1 && d[i].p >= d[cur].p + g[cur][i].p){
if(d[i].p == d[cur].p + g[cur][i].p){
if(d[i].v > d[cur].v + g[cur][i].v){
d[i].v = d[cur].v + g[cur][i].v;
}
else continue;
}
else {
d[i].p = d[cur].p + g[cur][i].p;
d[i].v = d[cur].v + g[cur][i].v;
}
if(!vis[i]){
vis[i] = 1;
q.push(i);
}
}
}
}
return ;
}
int main(){
int T, ss, tt, v, s, p, t;
char str[10];
//scanf("%d", &T);
while(~scanf("%d%d", &n, &m), n||m){
//mst(g, -1);
REP(i, 1, n+1)REP(j, 1, n+1){
g[i][j].p = -1;
g[i][j].v = -1;
}
REP(i, 0, m){
scanf("%d%d%d%d", &s, &t, &p, &v);
if(g[s][t].p != -1){
if(g[s][t].p > p){
g[s][t].p = g[t][s].p = p;
g[s][t].v = g[t][s].v = v;
}
else if(g[s][t].p == p && g[s][t].v > v){
g[s][t].v = g[t][s].v = v;
}
}
else {
g[s][t].p = g[t][s].p = p;
g[s][t].v = g[t][s].v = v;
}
}
/*
REP(i, 0, n)REP(j, 0, n){
printf("%.3f ", g[i][j]);
if(j == n-1)printf("\n");
}*/
scanf("%d%d", &ss, &tt);
spfa(ss);
printf("%d %d\n", d[tt].p, d[tt].v);
}
return 0;
}