void diji(int x){ fill(dis,dis+n,INT_MAX); dis[x] = 0; for(int i=0;i < n;i++) pre[i] = i; while(1){ int minn = INT_MAX; int v = -1; for(int i=0;i < n;i++){ if(!vis[i]&&dis[i] < minn){ v = i; minn = dis[i]; } } if(v == -1)break; vis[v] = 1; for(int i=0;i < n;i++){ if(!vis[i]&&cost1[i][v]!=INT_MAX&&dis[v]+cost1[i][v]<dis[i]){ dis[i] = dis[v] + cost1[i][v]; pre[i] = v; } } } }
初始化:
int main(){ int m,s; cin >> n >> m >> s >> d; for(int i=0;i < n;i++){ for(int j=0;j < n;j++){ cost1[i][j] = INT_MAX; cost1[i][i] = 0; } } for(int i=0;i < m;i++){ int x,y,a,b; cin >> x >> y >> a >> b; cost1[x][y] = a; cost1[y][x] = a; cost2[x][y] = b; cost2[y][x] = b; } diji(s); for(int i=0;i < n;i++) cout << pre[i] << " "; return 0; }
diji+dfs模板
#include<iostream> #include<vector> using namespace std; const int maxv = 510; const int INF = 1e9 + 10; int G[maxv][maxv], d[maxv], C[maxv][maxv]; int n, m, s, dd, mincost = INF; bool vis[maxv]; vector<int>pre[maxv]; vector<int>temp, path; void Dijkstra(int s) { fill(d, d + maxv, INF); d[s] = 0; while (1) { int u = -1, MIN = INF; for (int i = 0; i < n; i++) { if (!vis[i]&&d[i] < MIN)MIN = d[i], u = i; } if (u == -1)return; vis[u] = true; for (int i = 0; i < n; i++) { if (!vis[i] && G[u][i]) { if (d[u] + G[u][i] < d[i]) { d[i] = d[u] + G[u][i]; pre[i].clear(); //之前记录的不是最优的路,删去以后补上最优路的前项 pre[i].push_back(u); } else if (d[u] + G[u][i] == d[i]) { pre[i].push_back(u);//相等的话增加一个前项点 } } } } } void DFS(int v) { if (v == s) { temp.push_back(s); int tempcost = 0; for (int i = temp.size() - 1; i > 0; i--) { int v = temp[i]; int u = temp[i - 1]; tempcost += C[u][v]; } if (tempcost < mincost) { mincost = tempcost; path = temp; } temp.pop_back(); return; } temp.push_back(v); for (int i = 0; i < pre[v].size(); i++) DFS(pre[v][i]); temp.pop_back(); } int main() { scanf("%d%d%d%d", &n, &m, &s, &dd); for (int i = 0; i < m; i++) { int c1, c2, dis, cost; scanf("%d%d%d%d", &c1, &c2, &dis, &cost); G[c1][c2] = G[c2][c1] = dis; C[c1][c2] = C[c2][c1] = cost; } Dijkstra(s); DFS(dd); for (int i = path.size() - 1; i >= 0; i--)printf("%d ", path[i]); printf("%d %d", d[dd], mincost); return 0; }
——求相同路径的条数把pre[i]中有数的连城就好了8