1. 程式人生 > >Ant Man CodeForces - 704B (圖論,貪心)

Ant Man CodeForces - 704B (圖論,貪心)

scan pan ont ans sca The codeforce d+ define

大意: 給N個點,起點S終點T,每個點有X,A,B,C,D,根據I和J的X坐標可得I到J的距離計算公式

  • |xi?-?xj|?+?ci?+?bj seconds if j<?i
  • |xi?-?xj|?+?di?+?aj seconds otherwise (j >?i).

求從起點到終點,經過N個點恰好一次的最短路

這題好巧妙啊, 以前都沒見過這種做法, 看題解說是要維護一條從S->T的鏈, 每次貪心往鏈裏添點就行了, 顯然這個貪心是與順序無關的, 所以一定最優. 復雜度是$O(n^2)$的

#include <iostream>
#include <algorithm>
#include <cstdio>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;

const int N = 1e3+10;
int n, s, t;
int x[N], a[N], b[N], c[N], d[N], nxt[N];
ll g[N][N];

int main() {
	scanf("%d%d%d", &n, &s, &t);
	REP(i,1,n) scanf("%d", x+i);
	REP(i,1,n) scanf("%d", a+i);
	REP(i,1,n) scanf("%d", b+i);
	REP(i,1,n) scanf("%d", c+i);
	REP(i,1,n) scanf("%d", d+i);
	REP(i,1,n) REP(j,1,n) if (i!=j) {
		if (j<i) g[i][j]=(ll)abs(x[i]-x[j])+c[i]+b[j];
		else g[i][j]=(ll)abs(x[i]-x[j])+d[i]+a[j];
	}
	ll ans = g[s][t];
	nxt[s] = t;
	REP(i,1,n) if (i!=s&&i!=t) {
		ll mi = 1e18;
		int pos;
		for (int j=s,k; j!=t; j=k) {
			k = nxt[j];
			ll d = g[j][i]+g[i][k]-g[j][k];
			if (mi>d) mi = d, pos = j;
		}
		ans += mi;
		nxt[i] = nxt[pos];
		nxt[pos] = i;
	}
	printf("%lld\n", ans);
}

Ant Man CodeForces - 704B (圖論,貪心)