BZOJ1027 [JSOI2007]合金

來源:互聯網
上載者:User

標籤:

每個物品有三個參量,其實等價於兩個,因為總和確定。
於是問題變成二維平面上一堆點,求最小的b的子集形成的凸包,包含這些點a。
用Floyd繞一圈即可。

 

  1 /**************************************************************  2     Problem: 1027  3     User: rausen  4     Language: C++  5     Result: Accepted  6     Time:1136 ms  7     Memory:1820 kb  8 ****************************************************************/  9   10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13   14 #define P Point 15 using namespace std; 16 typedef double lf; 17 const int N = 505; 18 const int inf = 1e9; 19 const lf eps = 1e-8; 20   21 struct Point { 22     lf x, y; 23     P() {} 24     P(lf _x, lf _y) : x(_x), y(_y) {} 25       26     inline bool operator != (const P p) const { 27         return fabs(x - p.x) > eps || fabs(y - p.y) > eps; 28     } 29     inline P operator - (P p) { 30         return P(x - p.x, y - p.y); 31     } 32     inline lf operator * (P p) { 33         return x * p.y - y * p.x; 34     } 35       36     inline void read() { 37         scanf("%lf%lf%*lf", &x, &y); 38     } 39 } a[N], b[N]; 40   41 int n, m; 42 int dis[N][N]; 43   44 bool in_one_line(P x, P y) { 45     int i; 46     if (x.x > y.x) swap(x, y); 47     for (i = 1; i <= m; ++i) 48         if (b[i].x < x.x || b[i].x > y.x) return 0; 49     if (x.y > y.y) swap(x, y); 50     for (i = 1; i <= m; ++i) 51         if (b[i].y < x.y || b[i].y > y.y) return 0; 52     return 1; 53 } 54   55 int check(P x, P y) { 56     int i, cnt1, cnt2; 57     lf tmp; 58     for (i = 1, cnt1 = cnt2 = 0; i <= m; ++i) { 59         tmp = (y - x) * (b[i] - x); 60         if (tmp > eps) ++cnt1; 61         if (tmp < -eps) ++cnt2; 62         if (cnt1 && cnt2) return 0; 63     } 64     if (!cnt1 && !cnt2 && in_one_line(x, y)) { 65         puts("2"); 66         return -1; 67     } 68     return cnt1 ? 1 : cnt2 ? 2 : 3; 69 } 70   71 void Floyd() { 72     int ans = inf, i, j, k; 73     for (k = 1; k <= n; ++k) 74         for (i = 1; i <= n; ++i) 75             for (j = 1; j <= n; ++j) 76                 dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); 77     for (i = 1; i <= n; ++i) 78         ans = min(ans, dis[i][i]); 79     if (ans == inf || ans <= 2) puts("-1"); 80     else printf("%d\n", ans); 81 } 82   83 void solve() { 84     int i, j, f; 85     for (i = 1; i <= n; ++i) 86         for (j = 1; j <= n; ++j) 87             dis[i][j] = inf; 88     for (i = 1; i <= n; ++i) 89         for (j = i + 1; j <= n; ++j) { 90             f = check(a[i], a[j]); 91             if (f == -1) return; 92             if (f == 1) dis[i][j] = 1; 93             else if (f == 2) dis[j][i] = 1; 94             else if (f == 3) dis[i][j] = dis[j][i] = 1; 95         } 96     Floyd(); 97 } 98   99 bool special_judge() {100     int i;101     for (i = 1; i <= n; ++i)102         if (a[1] != a[i]) return 0;103     for (i = 1; i <= m; ++i)104         if (a[1] != b[i]) return 0;105     puts("1");106     return 1;107 }108  109 int main() {110     int i;111     scanf("%d%d", &n, &m);112     for (i = 1; i <= n; ++i)113         a[i].read();114     for (i = 1; i <= m; ++i)115         b[i].read();116     if (special_judge()) return 0;117     solve();118     return 0;119 }
View Code

 

BZOJ1027 [JSOI2007]合金

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.