1. 程式人生 > >CCF 201712-4 行車路線 最短路

CCF 201712-4 行車路線 最短路

tin ring font end vector 挑戰 span sizeof ret

題意:一張n個點的圖,有小路和大路,走大路花費的體力值是wi,如果連續走小路,花費的體力是連續走的小路的wi的和的平方,求1到n的最少花費體力

n <= 500, m <= 1e5

大一第一次考CCF的第四題,當年真的還是個最短路都不會的超級萌萌萌萌新,抄挑戰的最短路板子(毒瘤代碼)騙個40分的部分分,然後當時還怎麽想都不明白怎麽做

現在看起來就是裸的最短路各種各樣的條件這樣那樣一下而已了= -。。。

幾乎所有單源最短路問題都可以套用d[i]為起點到i點的最短路,這題也一樣,如果是小路就記錄一下連續走了多長的小路距離,換成新的體力花費然後松弛就行

 1 #include<cstdio>
 2
#include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<vector> 6 #include<queue> 7 #define INF 0x3f3f3f3f 8 #define LL long long 9 #define debug(x) cout << "[" << x << "]" << endl 10 using namespace std; 11 12 const
int maxn = 510; 13 struct edge{ 14 int v, id; 15 LL w; 16 edge(int v = 0, LL w = 0, int id = 0): v(v), w(w), id(id){} 17 bool operator < (const edge& a) const{ 18 return w > a.w; 19 } 20 }; 21 vector<edge> e[maxn]; 22 bool vis[maxn]; 23 LL d[maxn], sum[maxn];
24 25 void dijk(){ 26 memset(d, INF, sizeof d); 27 priority_queue<edge> q; 28 d[1] = 0; 29 q.push(edge(1, 0, 0)); 30 while (!q.empty()){ 31 int u = q.top().v; q.pop(); 32 if (vis[u]) continue; 33 vis[u] = 1; 34 for (int i = 0; i < e[u].size(); i++){ 35 int v = e[u][i].v; 36 LL w = e[u][i].w, cost = 0; 37 if (e[u][i].id == 1){ 38 LL tmp = sum[u]+w; 39 cost = d[u]-sum[u]*sum[u]+tmp*tmp; 40 } 41 else cost = d[u]+w; 42 if (d[v] > cost){ 43 d[v] = cost; 44 if (e[u][i].id == 1) sum[v] = sum[u]+w; 45 else sum[v] = 0; 46 q.push(edge(v, d[v], 0)); 47 } 48 } 49 } 50 } 51 52 int main(){ 53 int n, m, t, a, b; 54 LL c; 55 scanf("%d%d", &n, &m); 56 for (int i = 0; i < m; i++){ 57 scanf("%d%d%d%lld", &t, &a, &b, &c); 58 e[a].push_back(edge(b, c, t)); 59 e[b].push_back(edge(a, c, t)); 60 } 61 dijk(); 62 printf("%lld\n", d[n]); 63 return 0; 64 }

CCF 201712-4 行車路線 最短路