洛谷 P3110 [USACO14DEC]Piggy Back S
阿新 • • 發佈:2020-10-25
題目傳送門
因為每條邊的長度是相同的,所以用bfs就行.當背起來走不比分開更優時,分別跑bfs就行.
當更優時,處理出每個點到1,2,n的距離,然後更新答案.
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,m,b,p,r,tot,head[400001],ans = 2099999999,dis1[400001],dis[400001],dis2[400001]; bool vis[400001]; struct kkk { int to,next; }e[80002]; inline void add(int x,int y) { e[++tot].to = y; e[tot].next = head[x]; head[x] = tot; } inline void bfs(int s) { memset(dis,0x3f3f3f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int> q; vis[s] = 1; q.push(s); dis[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u];i; i = e[i].next) { int v = e[i].to; if(dis[v] > dis[u] + 1) { dis[v] = dis[u] + 1; if(!vis[v]) q.push(v); } } } } inline void bfs1(int s) { memset(dis1,0x2f,sizeof(dis1)); memset(vis,0,sizeof(vis)); queue<int> q; vis[s] = 1; q.push(s); dis1[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u];i; i = e[i].next) { int v = e[i].to; if(dis1[v] > dis1[u] + 1) { dis1[v] = dis1[u] + 1; if(!vis[v]) q.push(v); } } } } inline void bfs2(int s) { memset(dis2,0x2f,sizeof(dis1)); memset(vis,0,sizeof(vis)); queue<int> q; vis[s] = 1; q.push(s); dis2[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = 0; for(int i = head[u];i; i = e[i].next) { int v = e[i].to; if(dis2[v] > dis2[u] + 1) { dis2[v] = dis2[u] + 1; if(!vis[v]) q.push(v); } } } } int main() { scanf("%d%d%d%d%d",&b,&r,&p,&n,&m); for(int i = 1;i <= m; i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } if(p >= b + r) { bfs(1); ans = dis[n] * b; bfs(2); ans += dis[n] * r; printf("%d",ans); return 0; } bfs(1); bfs1(2); bfs2(n); for(int i = 1;i <= n; i++) ans = min(ans,dis1[i] * r + dis[i] * b + dis2[i] * p); printf("%d",ans); return 0; }