题目大意:在一个充满魔法的国家,有一种魔法卡片,它可以使你行走的时间减半。给一张无向图,并告诉你有k个魔法卡片,问你最快多长时间能够从1到N。
思路:经典的分层图模型,SPFA使将dis数组和vis数组开成二维,纪录一维层数信息即可
CODE(1A,开心):
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 5000 #define INF 0x3f3f3f3f using namespace std; struct Complex{ int pos,step; Complex(int _step,int _pos):step(_step),pos(_pos) {} Complex() {} }; int points,edges,k; int head[MAX],total; int _next[MAX],aim[MAX],length[MAX]; int f[60][MAX]; bool v[60][MAX]; inline void Add(int x,int y,int len); void SPFA(); int main() { cin >> points >> edges >> k; for(int x,y,z,i = 1;i <= edges; ++i) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z),Add(y,x,z); } SPFA(); int ans = INF; for(int i = 0;i <= k; ++i) ans = min(ans,f[i][points]); cout << ans << endl; return 0; } inline void Add(int x,int y,int len) { _next[++total] = head[x]; aim[total] = y; length[total] = len; head[x] = total; } void SPFA() { static queue<Complex> q; memset(f,0x3f,sizeof(f)); memset(v,false,sizeof(v)); f[0][1] = 0; q.push(Complex(0,1)); while(!q.empty()) { Complex temp = q.front(); q.pop(); int x = temp.pos,step = temp.step; for(int i = head[x];i;i = _next[i]) { if(f[step][aim[i]] > f[step][x] + length[i]) { f[step][aim[i]] = f[step][x] + length[i]; if(!v[step][aim[i]]) { v[step][aim[i]] = true; q.push(Complex(step,aim[i])); } } if(step + 1 <= k && f[step + 1][aim[i]] > f[step][x] + (length[i] >> 1)) { f[step + 1][aim[i]] = f[step][x] + (length[i] >> 1); if(!v[step + 1][aim[i]]) { v[step + 1][aim[i]] = true; q.push(Complex(step + 1,aim[i])); } } } } }