Cod sursa(job #658282)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 8 ianuarie 2012 14:58:55
Problema Portal3 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.82 kb
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <string>

#define f first
#define s second
#define N 3
#define MAXN 10
#define ll long long
#define mp make_pair
#define pb push_back
using namespace std;


int X1[N + 1], X2[N + 1], Y1[N + 1], Y2[N + 1];
bool viz[MAXN];
vector <pair <int, ll> > G[MAXN];
ll C[MAXN];
int go1, go2;
inline int abs(int x) {
	if( x < 0) return -x;
	return x;
}
inline ll dist(int x1, int y1, int x2, int y2) {
	return abs(y2 - y1) + abs(x2 - x1);
}

inline void BF(int source) {
	
	queue <int> Q;
	Q.push(source);
	const long long INF = 1LL << 62;	
	
	for(int i = 0; i <= MAXN; i++)
		C[i] = INF;
//	printf("%lld\n", C[0]);
	memset(viz, 0, sizeof(viz));

	C[0] = 0;
	int node;
	while(!Q.empty()) {
		node = Q.front();
		Q.pop();
		viz[node] = 0;
		for(vector <pair <int, ll> > :: iterator it = G[node].begin(); it != G[node].end(); it++)
			if(C[it -> f] > C[node] + it -> s) {
				C[it -> f] = C[node] + it -> s;
				if(!viz[it -> f]) {
					viz[it -> f] = 1;
					Q.push(it -> f);
				}
			}
	}
}
int T;
int main() {


	freopen("portal3.in", "r", stdin);
	freopen("portal3.out", "w", stdout);

	ll cost[N + 3];
	for(scanf("%d\n", &T); T--; ) {
		
		scanf("%d%d\n", &go1, &go2);
	
		for(int i = 1; i <= N; i++) {
			scanf("%d %d %d %d %lld\n", &X1[i], &Y1[i], &X2[i], &Y2[i], &cost[i]);
			ll d = dist(X1[i], Y1[i], X2[i], Y2[i]);
			G[2 * i].pb(mp(2*i + 1, min(cost[i], d)));
			G[2 * i + 1].pb(mp(2 * i, min(cost[i], d)));
		}
		for(int i = 1; i <= N; i++) {
			ll d1, d2;
			d1 = dist(X1[i], Y1[i], 0, 0);
			d2 = dist(X2[i], Y2[i], 0, 0);
			
			//muchii intre (0, 0) -> 2 * i, 2 * i + 1
			G[0].pb(mp(2 * i, d1)); G[0].pb(mp(2 * i + 1, d2));
			G[2*i].pb(mp(0,d1)); G[2*i+1].pb(mp(0,d2));
			
			d1 = dist(X1[i], Y1[i], go1, go2);
			d2 = dist(X2[i], Y2[i], go1, go2);
			//muchii intre 2*i, 2*i+1, (go1, go2)
			G[2 * i].pb(mp(2 * N + 2, d1)); G[2 * i + 1].pb(mp(2 * N + 2, d2));
			
			for(int j = i + 1; j <= N; j++) {
				if(j > N) break;
				
				//muchii intre toate nodurile
				d1 = dist(X1[i], Y1[i], X1[j], Y1[j]);
				d2 = dist(X1[i], Y1[i], X2[j], Y2[j]);
				
				G[2*i].pb(mp(2*j, d1)); G[2*i].pb(mp(2*j+1,d2));
				G[2*j].pb(mp(2*i, d1)); G[2*j+1].pb(mp(2*i, d2));			
				d1 = dist(X2[i], Y2[i], X1[j], Y1[j]);
				d2 = dist(X2[i], Y2[i], X2[j], Y2[j]);
				
				G[2*i+1].pb(mp(2*j, d1)); G[2*i+1].pb(mp(2*j+1,d2));
				G[2*j].pb(mp(2*i+1, d1)); G[2*j+1].pb(mp(2*i+1,d2));
			}
		}
		G[0].pb(mp(2 * N + 2, go1 + go2));
		
		BF(0);
		ll mn = C[2 * N + 2];
		for(int i = 1; i <= N; i++) {
			if(X1[i] == go1 && Y1[i] == go2) 
				mn = min(mn, C[2 * i]);
			if(X2[i] == go1 && Y2[i] == go2)
				mn = min(mn, C[2 * i + 1]);
		}
		printf("%lld\n", mn);
		for(int i = 0; i <= 2 * N + 2; i++)
			G[i].clear();
		for(int i = 0; i <= 2 * N + 2; i++) {
//			printf("%lld\n", C[i]);
			C[i] = 0;
		}
	}
	return 0;
}