小记:这题其实是比较水的,之所以没把它算出水题,是我个人问题,竟然忘记输入判重了,然后就一直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; }