zoukankan      html  css  js  c++  java
  • BZOJ 1027: [JSOI2007]合金 (计算几何+Floyd求最小环)

    题解就看这位仁兄的吧…不过代码还是别看他的了…

    同样的方法…我200ms,他2000ms.

    常数的幽怨…

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 505;
    const double eps = 1e-8;
    struct Point {
    	double x, y;
    	Point(){}
    	Point(double x, double y):x(x), y(y){}
    	inline Point operator -(const Point &o)const { return Point(x-o.x, y-o.y); }
    	inline double operator *(const Point &o)const { return x*o.y - y*o.x; } 
    }a[MAXN], b[MAXN];
    struct Line {
    	Point p, v;
    	Line(){}
    	Line(const Point &p, const Point &v):p(p), v(v){}
    };
    inline bool On_Right(const Line &l, const Point &p) {
    	return (p - l.p) * l.v > eps;
    }
    inline int dcmp(const double &x) {
    	return x < -eps ? -1 : x < eps ? 0 : 1;
    }
    int m, n, f[MAXN][MAXN];
    int main () {
    	scanf("%d%d", &m, &n); double o;
    	for(int i = 1; i <= m; ++i) scanf("%lf%lf%lf", &a[i].x, &a[i].y, &o);
    	for(int i = 1; i <= n; ++i) scanf("%lf%lf%lf", &b[i].x, &b[i].y, &o);
    	for(int i = 1; i <= m; ++i) {
    		for(int j = 1; j <= m; ++j)
    			f[i][j] = m+1;
    		bool flg = 1;
    		for(int j = 1; j <= n && flg; ++j)
    			if(dcmp(b[j].x-a[i].x) || dcmp(b[j].y-a[i].y)) flg = 0;
    		if(flg) return puts("1"), 0;
    	}
    	for(int i = 1; i <= m; ++i)
    		for(int j = 1; j <= m; ++j)
    			if(i != j && !(a[i].x == a[j].x && a[i].y == a[j].y)) { //i->j
    				Line tmp = Line(a[i], a[j] - a[i]);
    				bool flg = 1;
    				for(int k = 1; k <= n && flg; ++k)
    					if(On_Right(tmp, b[k])) flg = 0;
    				if(flg) {
    					for(int k = 1; k <= n && flg; ++k)
    						if
    						(
    							(!dcmp((b[k] - tmp.p) * tmp.v))
    							&&
    							((b[k].x < a[i].x && b[k].x < a[j].x)
    							|| (b[k].x > a[i].x && b[k].x > a[j].x)
    							|| (b[k].y < a[i].y && b[k].y < a[j].y)
    							|| (b[k].y > a[i].y && b[k].y > a[j].y)
    							)
    						) flg = 0;
    					if(flg) f[i][j] = 1;
    				}
    			}
    	for(int k = 1; k <= m; ++k)
    		for(int i = 1; i <= m; ++i) if(f[i][k] <= m)
    			for(int j = 1; j <= m; ++j) if(f[k][j]+f[i][k] <= m)
    				f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
    	int ans = m+1;
    	for(int i = 1; i <= m; ans = min(ans, f[i][i]), ++i);
    	printf("%d
    ", ans > m ? -1 : ans);
    }
    
  • 相关阅读:
    c# 异步和同步问题(转载)
    用Python作GIS之四:Tkinter基本界面的搭建
    Linux必知必会--vmstat
    Linux必知必会--awk
    Linux必知必会--sed
    Linux必知必会--grep
    Linux必知必会--curl
    康威定律
    移动端抓包合集
    MySQL重置自增id
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039295.html
Copyright © 2011-2022 走看看