bzoj 1027 floyd求有向图最小环

1 /**************************************************************
2     Problem: 1027
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:1308 ms
7     Memory:2008 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cmath>
12 #include <cstring>
13 #include <algorithm>
14 #define line(a,b) ((b)-(a))
15 #define eps 1e-8
16 #define oo 0x3f3f3f3f
17 #define N 550
18 using namespace std;
19
20 int sg( double x ) { return (x>-eps)-(x<eps); }
21 struct Vector {
22     double x, y;
23     Vector(){}
24     Vector( double x, double y ):x(x),y(y){}
25     Vector operator-( const Vector &b ) const { return Vector(x-b.x,y-b.y); }
26     double operator^( const Vector &b ) const { return x*b.y-y*b.x; }
27     double operator&( const Vector &b ) const { return x*b.x+y*b.y; }
28     double len() { return sqrt(x*x+y*y); }
29     bool operator<( const Vector &b ) const {
30         return sg(x-b.x)<0 || (sg(x-b.x)==0 && sg(y-b.y)<0);
31     }
32     bool operator==( const Vector &b ) const {
33         return sg(x-b.x)==0 && sg(y-b.y)==0;
34     }
35 };
36 typedef Vector Point;
37
38 int n, m;
39 Point aa[N], bb[N];
40 int dis[N][N];
41
42 bool onleft( const Point &a, const Point &b, const Point &c ) {
43     return sg(line(a,b)^line(a,c))>=0;
44 }
45 bool onseg( const Point &a, const Point &b, const Point &c ) {
46     return sg(line(a,b)^line(a,c))==0 && sg(line(c,a)&line(c,b))<0;
47 }
48 bool case1() {
49     if( m==1 ) {
50         for( int i=1; i<=n; i++ )
51             if( aa[i]==bb[1] )
52                 return true;
53     }
54     return false;
55 }
56 bool case2() {
57     bool ok = true;
58     for( int i=1; i<=m && ok; i++ )
59         for( int j=i+1; j<=m && ok; j++ )
60             for( int k=j+1; k<=m && ok; k++ )
61                 if( sg((bb[i]-bb[j])^(bb[k]-bb[j])) )
62                     ok =false;
63     if( ok ) {
64         int ii=1, jj=1;
65         double ll = -1.0;
66         for( int i=1; i<=m; i++ )
67             for( int j=i+1; j<=m; j++ ) {
68                 double l = (bb[i]-bb[j]).len();
69                 if( l>ll ) {
70                     ii = i;
71                     jj = j;
72                     ll = l;
73                 }
74             }
75         for( int i=1; i<=n; i++ )
76             for( int j=i+1; j<=n; j++ )
77                 if( onseg(aa[i],aa[j],bb[ii]) && onseg(aa[i],aa[j],bb[jj]) )
78                     return true;
79     }
80     return false;
81 }
82 int main() {
83     scanf( "%d%d", &n, &m );
84     for( int i=1; i<=n; i++ ) {
85         double x, y, z;
86         scanf( "%lf%lf%lf", &x, &y, &z );
87         aa[i] = Point(x,y);
88     }
89     for( int i=1; i<=m; i++ ) {
90         double x, y, z;
91         scanf( "%lf%lf%lf", &x, &y, &z );
92         bb[i] = Point(x,y);
93     }
94     sort( bb+1, bb+1+m );
95     m = unique( bb+1, bb+1+m ) - bb - 1;
96     sort( aa+1, aa+1+n );
97     n = unique( aa+1, aa+1+n ) - aa - 1;
98     if( case1() ) {
99         printf( "1\n" );
100         return 0;
101     } else if( case2() ) {
102         printf( "2\n" );
103         return 0;
104     }
105     memset( dis, 0x3f, sizeof(dis) );
106     for( int u=1; u<=n; u++ )
107         for( int v=1; v<=n; v++ ) {
108             if( u==v ) continue;
109             bool ok = true;
110             for( int k=1; k<=m; k++ )
111                 if( !onleft(aa[u],aa[v],bb[k]) ) {
112                     ok = false;
113                     break;
114                 }
115             if( ok ) {
116                 dis[u][v] = 1;
117             }
118         }
119     for( int k=1; k<=n; k++ )
120         for( int i=1; i<=n; i++ )
121             for( int j=1; j<=n; j++ )
122                 dis[i][j] = min( dis[i][j], dis[i][k]+dis[k][j] );
123     int ans = oo;
124     for( int i=1; i<=n; i++ ) {
125         if( dis[i][i]==2 ) continue;
126         ans = min( ans, dis[i][i] );
127     }
128     printf( "%d\n", ans==oo ? -1 : ans );
129 }
View Code

posted @ 2015-05-27 20:16  idy002  阅读(280)  评论(0编辑  收藏  举报