第一眼就觉得肯定某种是最短路,然后想了半天也不知道。然后就把送的50分写了,然后就爆搜,结果因为一个错误的剪枝竟然90分?!只能怪数据太水……
考完试后听bin哥讲,说就是普通的最短路,只不过一个dis[i]表示1到 i 的最短路,step[i]表示1到 i 要有几个点,然后判断点v是否加入队列分两种情况:1.v没被走过。2.dis[v] / step[v] > (dis[u] + cost[u->v]) / (step[u] + 1)。
还有一点不同的是,对于判断是否已经进过队列不能再用一维表示了,因为用不同的走法又走到了点u,答案可能更优,因为开两位inq[u][j]表示 j 步走到u这个状态已经进过队列了。
突然又想到了一点,dis[i]不用初始化为INF,因为判断的条件变了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 205; 20 const int maxm = 2e3 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int n, m; 38 vector<int> v[maxn], c[maxn]; 39 40 #define pr pair<int, int> 41 #define mp make_pair 42 int dis[maxn], step[maxn], pre[maxn]; 43 bool inq[maxn][maxm]; 44 void dijkstra(int s) 45 { 46 step[s] = 1; 47 priority_queue<pr, vector<pr>, greater<pr> > q; 48 q.push(mp((db)dis[s] / (db)step[s], s)); 49 while(!q.empty()) 50 { 51 int now = q.top().second; q.pop(); 52 if(inq[now][step[now]]) continue; 53 inq[now][step[now]] = 1; 54 for(int i = 0; i < (int)v[now].size(); ++i) 55 { 56 if((!dis[v[now][i]] || !step[v[now][i]]) || (db)dis[v[now][i]] / (db)step[v[now][i]] > (db)(dis[now] + c[now][i]) / (db)(step[now] + 1)) 57 { 58 dis[v[now][i]] = dis[now] + c[now][i]; 59 step[v[now][i]] = step[now] + 1; 60 q.push(mp((db)dis[v[now][i]] / (db) step[v[now][i]], v[now][i])); 61 } 62 } 63 } 64 printf("%.6lf ", (db)dis[n] / step[n]); 65 } 66 67 int main() 68 { 69 freopen("calabash.in", "r", stdin); 70 freopen("calabash.out", "w", stdout); 71 n = read(); m = read(); 72 for(int i = 1; i <= m; ++i) 73 { 74 int x = read(), y = read(), co = read(); 75 v[x].push_back(y); c[x].push_back(co); 76 } 77 dijkstra(1); 78 return 0; 79 }