1. 程式人生 > >CCF 201712-4 90分

CCF 201712-4 90分

while limit ++ min ccf string pos ons markdown

90分,不知道錯在哪裏了,dijkstra算法,用一個數組的d[i]表示以i點結尾的小路的長度,以i點為中心擴展時,若下一點為k,如果i->k是小路,則
d[j] = d[k]+M[k][j];dist[j] = min_ - pow(d[k], 2) + pow(d[j], 2);
否則直接加路徑長度即可,同時把d[j]=0

#include <iostream>
#include <cstdio>
#include <climits>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std; const int INF = 100000000; const int MAXN = 505; int M[MAXN][MAXN]; int kind[MAXN][MAXN]; int dijkstra(int n) { int flag[MAXN]; long long dist[MAXN]; int k; int d[MAXN]; memset(flag, 0, sizeof(flag)); memset(d, 0, sizeof(d)); for (int i = 0; i < n; i++) { if
(M[0][i] > 0) { if (kind[0][i] == 0) dist[i] = M[0][i]; else { dist[i] = pow(M[0][i], 2); d[i] = M[0][i]; } } else dist[i] = -1; } flag[0] = 1; dist[0] = 0
; for (int i = 1; i < n; i++) { int min_ = INF; for (int j = 0; j < n; j++) { if (!flag[j]&&dist[j]>0&&dist[j]<min_) { min_ = dist[j]; k = j; } } flag[k] = 1; for (int j = 0; j < n; j++) { if (!flag[j] && M[j][k]>0) { if (dist[j] < 0) { if (kind[k][j] == 0) { d[j] = 0; dist[j] = min_ + M[j][k]; } else { d[j] = d[k]+M[j][k]; dist[j] = min_ - pow(d[k], 2) + pow(d[k] + M[j][k],2); } continue; } if (dist[j] > 0) { if (kind[k][j] == 0) { if (dist[j] > min_ + M[j][k]) { dist[j] = min_ + M[j][k]; d[j] = 0; } } else { int temp = min_ - pow(d[k], 2) + pow(d[k] + M[k][j], 2); if (dist[j] > (min_ - pow(d[k], 2) + pow(d[k]+M[k][j], 2))) { d[j] = d[k]+M[k][j]; dist[j] = min_ - pow(d[k], 2) + pow(d[j], 2); } } continue; } } } } return dist[n-1]; } int main() { int n, m; while (~scanf("%d %d",&n,&m)) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (i == j)M[i][j] = 0; else M[i][j] = -1; memset(kind, 0, sizeof(kind)); for (int i = 0; i < m; i++) { int k, a, b, c; scanf("%d %d %d %d", &k, &a, &b, &c); M[a-1][b-1] = M[b-1][a-1] = c; kind[a-1][b-1] = kind[b-1][a-1] = k; } cout<<dijkstra(n)<<endl; } return 0; }

CCF 201712-4 90分