还是用的spfa算法,wa了好多次,又是因为输入的时候可能有重复的边,甚至还可能出现边的权值相同,但是花费
不同。。。wa了好几次,还有忘了删多余的代码。。。血淋淋的教训啊。。。
思路:就是多加了一个花费,没多大的区别,还是用的spfa方法,就是在距离相等的时候更新一下花费就可以了,
距离不相等的时候都更新。
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set> #include<string> #include<algorithm> #include<queue> #define MAX 0x7fffffff using namespace std; bool visit[1005]; int gra[1005][1005]; int d[1005]; int cc[1005]; int cost[1005][1005]; int main() { //freopen("D:/input.txt","r",stdin); //freopen("D:/output.txt","w",stdout); int n ,m,a,b,c,dd,i,j,s,t; vector<int>v[1005]; while(scanf("%d%d",&n,&m),n||m) { for(i=1; i<=n; i++) visit[i] = false; for(i=1; i<=n; i++) v[i].clear(); for(i=1; i<=n; i++) for(j=1; j<=n; j++) { gra[i][j] = gra[j][i] = MAX; cost[i][j] = cost[j][i] = MAX; } for(i=1; i<=m; i++) { scanf("%d%d%d%d",&a,&b,&c,&dd); v[a].push_back(b); v[b].push_back(a); if(gra[a][b] > c) { gra[a][b] = gra[b][a] = c; cost[a][b] = cost[b][a] = dd; } else if(gra[a][b] == c && cost[a][b] > dd) cost[a][b] = cost[b][a] = dd; } for(i=1; i<=n; i++) d[i] = MAX; for(i=1; i<=n; i++) cc[i] = MAX; queue<int >q; //cin >> s >> t; scanf("%d%d",&s,&t); cc[s] = 0; d[s] = 0; visit[s] = true; q.push(s); while(!q.empty()) { int y = q.front(); q.pop(); visit[y] = false; for(i=0; i<v[y].size(); i++)//更新它邻接的点,注意这里更新的时候gra[i][j]不会是无穷大,因为邻接的点都有权值了。。。 { if(d[v[y][i]] > d[y] + gra[y][v[y][i]]) { d[v[y][i]] = d[y] + gra[y][v[y][i]]; cc[v[y][i]] = cc[y] + cost[y][v[y][i]]; if(!visit[v[y][i]])// 如果该点已经在队列中了,就不加进去 { q.push(v[y][i]); visit[v[y][i]] = true; } } else if(d[v[y][i]] == d[y] + gra[y][v[y][i]]) { if(cc[v[y][i]] > cc[y] + cost[y][v[y][i]]) cc[v[y][i]] = cc[y] + cost[y][v[y][i]]; if(!visit[v[y][i]])// 如果该点已经在队列中了,就不加进去 { q.push(v[y][i]); visit[v[y][i]] = true; } } } } cout << d[t] << " "<< cc[t] << endl; } return 0; }