http://poj.org/problem?id=1556
首先路径的每条线段一定是端点之间的连线。证明?这是个坑...反正我是随便画了一下图然后就写了..
然后re是什么节奏?我记得我开够了啊...然后再开大点才a...好囧啊.
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> using namespace std; typedef long long ll; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define read(a) a=getint() #define print(a) printf("%d", a) #define dbg(x) cout << (#x) << " = " << (x) << endl #define error(x) (!(x)?puts("error"):0) #define rdm(x, i) for(int i=ihead[x]; i; i=e[i].next) inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; } const double eps=1e-6; int dcmp(double x) { return abs(x)<eps?0:(x<0?-1:1); } struct ipoint { double x, y; }; double icross(ipoint &a, ipoint &b, ipoint &c) { static double x1, x2, y1, y2; x1=a.x-c.x; y1=a.y-c.y; x2=b.x-c.x; y2=b.y-c.y; return x1*y2-x2*y1; } int ijiao(ipoint &p1, ipoint &p2, ipoint &q1, ipoint &q2) { return (dcmp(icross(p1, q1, q2))^dcmp(icross(p2, q1, q2)))==-2 && (dcmp(icross(q1, p1, p2))^dcmp(icross(q2, p1, p2)))==-2; } const int N=1000; struct dat { int next, to; double w; }e[N<<2]; int ihead[N], cnt; void add(int u, int v, double w) { e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].w=w; } double spfa(int s, int t, int n) { static double d[N]; static int q[N], front, tail, u, v; static bool vis[N]; front=tail=0; for1(i, 0, n) vis[i]=0, d[i]=1e99; d[s]=0; q[tail++]=s; vis[s]=1; while(front!=tail) { u=q[front++]; if(front==N) front=0; vis[u]=0; rdm(u, i) if(d[v=e[i].to]+eps>d[u]+e[i].w) { d[v]=d[u]+e[i].w; if(!vis[v]) { vis[v]=1; if(d[v]<d[q[front]]+eps) { --front; if(front<0) front+=N; q[front]=v; } else { q[tail++]=v; if(tail==N) tail=0; } } } } return d[t]; } ipoint p[N], line[N*3][2]; int n, pn, ln; bool check(ipoint &x, ipoint &y) { for1(i, 1, ln) if(ijiao(x, y, line[i][0], line[i][1])) return false; return true; } double sqr(double x) { return x*x; } double dis(ipoint &x, ipoint &y) { return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y)); } int main() { while(read(n), n!=-1) { ln=0; pn=0; ++pn; p[pn].x=0; p[pn].y=5; ++pn; p[pn].x=10; p[pn].y=5; static double rx, ry[4]; while(n--) { scanf("%lf", &rx); rep(k, 4) scanf("%lf", &ry[k]); ++ln; line[ln][0]=(ipoint){rx, 0}; line[ln][1]=(ipoint){rx, ry[0]}; ++ln; line[ln][0]=(ipoint){rx, ry[1]}; line[ln][1]=(ipoint){rx, ry[2]}; ++ln; line[ln][0]=(ipoint){rx, ry[3]}; line[ln][1]=(ipoint){rx, 10}; rep(k, 4) ++pn, p[pn].x=rx, p[pn].y=ry[k]; } for1(i, 1, pn) for1(j, 1, pn) if(i!=j && check(p[i], p[j])) add(i, j, dis(p[i], p[j])); printf("%.2f\n", spfa(1, 2, pn)); memset(ihead, 0, sizeof(int)*(pn+1)); cnt=0; } return 0; }
Description
Input
Output
Sample Input
1 5 4 6 7 8 2 4 2 7 8 9 7 3 4.5 6 7 -1
Sample Output
10.00 10.06
Source