洛谷 P3110 [USACO14DEC]Piggy Back S

題目傳送門

因爲每條邊的長度是相同的,所以用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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章