Listing 1519
Submitted by asdf, 14 August 2008
#include <stdio.h>
#include <memory.h>
#define MD 101
#define MN 26
#define ML 12
#define oo 2147483647
#define Bint long long
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
int f(int a)
{if (a < 0) return -a; return a;}
struct Point {
int x, y;
}S, E;
int g(Point a, Point b, Point c) {
int re = oo;
re = min(f(a.x-c.x)+f(a.y-c.y),f(b.x-c.x)+f(b.y-c.y));
if (a.x == b.x && min(a.y,b.y)<c.y&&c.y<max(a.y,b.y))
re = min(f(a.x-c.x),re);
if (a.y == b.y && min(a.x,b.x)<c.x&&c.x<max(a.x,b.x))
re = min(f(a.y-c.y),re);
return re;
}
int ccw(Point a, Point b, Point c) {
Bint D = 0;
D += (Bint)a.x*b.y+(Bint)b.x*c.y+(Bint)c.x*a.y;
D -= (Bint)a.y*b.x+(Bint)b.y*c.x+(Bint)c.y*a.x;
if (D > 0) return 1;
if (D < 0) return -1;
return 0;
}
bool cr(Point a, Point b, Point c, Point d) {
if (ccw(a,b,c)*ccw(a,b,d) > 0) return 0;
if (ccw(c,d,a)*ccw(c,d,b) > 0) return 0;
return 1;
}
struct Path {
int n, f;
Point v[ML];
}d[MN];
int D, n, r;
void input()
{
int i, j;
scanf("%d%d%d%d%d%d", &D, &S.x, &S.y, &E.x, &E.y, &n);
for (i = 1; i <= n; i++) {
scanf("%d%d", &d[i].n, &d[i].f);
for (j = 1; j <= d[i].n; j++)
scanf("%d%d", &d[i].v[j].x, &d[i].v[j].y);
d[i].v[d[i].n+1] = d[i].v[1];
}
}
int dis[MN][MN];
int getdis(int a, int b)
{
int re, i, j;
re = oo;
for (i = 1; i <= d[a].n; i++) {
for (j = 1; j <= d[b].n; j++) {
if (cr(d[a].v[i],d[a].v[i+1],d[b].v[j],d[b].v[j+1])) return 0;
re = min(g(d[a].v[i],d[a].v[i+1],d[b].v[j]),re);
re = min(g(d[b].v[j],d[b].v[j+1],d[a].v[i]),re);
}
}
return re;
}
int getdis(Point a, int k)
{
int re, i;
re = oo;
for (i = 1; i <= d[k].n; i++)
re = min(g(d[k].v[i],d[k].v[i+1],a),re);
return re;
}
int c[MD][MN];
bool vis[MD][MN];
void process()
{
if (f(S.x-E.x)+f(S.y-E.y) <= D) {
printf("0\n");
return;
}
int i, j, k, t;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++)
dis[i][j] = getdis(i,j);
}
memset(c,128,sizeof(c));
for (i = 1; i <= n; i++) {
t = getdis(S,i);
if (t <= D)
c[getdis(S,i)][i] = d[i].f;
}
memset(vis,0,sizeof(vis));
r = oo;
for (i = 0; i <= D; i++) {
for (;;) {
k = -1;
for (j = 1; j <= n; j++) {
if (c[i][j] >= 0 && !vis[i][j]) {
if (k == -1) k = j;
else if (c[i][k] < c[i][j]) k = j;
}
}
if (k == -1) break;
vis[i][k] = 1;
t = i+getdis(E,k);
if (t <= D)
r = min(c[i][k],r);
else {
for (j = 1; j <= n; j++) {
t = i+dis[k][j];
if (t <= D) {
if (c[t][j] > c[i][k]+d[j].f || c[t][j] < 0)
c[t][j] = c[i][k]+d[j].f;
}
}
}
}
}
if (r == oo) printf("-1\n");
else printf("%d\n", r);
}
int main()
{
freopen("input.txt", "r", stdin);
input();
process();
return 0;
}
