35個點就亂著色啦XD
(幾何part由西瓜提供XD)
- #include<cstdio>
- #include<cstdlib>
- #include<algorithm>
- #include<cstring>
- #include<vector>
- #include<utility>
- #include<map>
- #include<set>
- #include<queue>
- #include<cmath>
- #define X first
- #define Y second
- using namespace std;
- typedef long long int int64;
- typedef pair<int,int> pii;
- pii operator-(const pii &a, const pii &b){
- return pii(a.X - b.X, a.Y - b.Y);
- }
- inline int dot(pii p1, pii p2){
- return p1.X * p2.X + p1.Y * p2.Y;
- }
- inline int cross(pii p1, pii p2){
- return p1.X * p2.Y - p2.X * p1.Y;
- }
- bool check(pii p1, pii p2, pii p3, pii p4){
- if((p1 == p3) and (p2 == p4)) return true;
- if((p1 == p4) and (p2 == p3)) return true;
- if ((p2.Y - p1.Y) * (p4.X - p3.X) != (p4.Y - p3.Y) * (p2.X - p1.X)) return false;
- if (cross(p2 - p1, p3 - p1)) return false;
- if (dot(p1 - p3, p1 - p4) < 0 || dot(p2 - p3, p2 - p4) < 0 ||
- dot(p3 - p1, p3 - p2) < 0 || dot(p4 - p1, p4 - p2) < 0)
- return true;
- return false;
- }
- vector<int> to[100];
- int col[100];
- void color(int prc){
- //printf("draw at %d\n", prc);
- int ctab[5] = {0};
- for(int lx = 0;lx < to[prc].size();lx++){
- int pind = to[prc][lx];
- if(col[pind] != -1)
- ctab[col[pind]] = 1;
- }
- int get_color = 4;
- for(int lx = 1;lx <= 4;lx++){
- if(ctab[lx] == 0){
- get_color = lx;
- break;
- }
- }
- col[prc] = get_color;
- //printf("draw %d\n", get_color);
- int a[100];
- for(int lx = 0;lx < to[prc].size();lx++){ a[lx] = lx; }
- random_shuffle(a, a+to[prc].size());
- for(int ly = 0;ly < to[prc].size();ly++){
- int pind = to[prc][a[ly]];
- if(col[pind] != -1) continue;
- color(pind);
- }
- return;
- }
- int main()
- {
- int n;
- srand(514514);
- for(;;){
- scanf("%d", &n);
- if(n == 0) break;
- pii polys[100][100];
- int ptcnt[100] = {0};
- bool metr[100][100] = {0};
- for(int lx = 0;lx < n;lx++)
- to[lx].clear();
- for(int lx = 0;lx < n;lx++){
- scanf("%d", ptcnt+lx);
- for(int ly = 0;ly < ptcnt[lx];ly++)
- scanf("%d %d", &polys[lx][ly].X, &polys[lx][ly].Y);
- }
- for(int lx = 0;lx < n;lx++){
- for(int ly = lx+1;ly < n;ly++){
- //printf("cal %d -> %d\n", lx, ly);
- bool ok = false;
- for(int la = 0;la < ptcnt[lx] and not ok; la++){
- for(int lb = 0;lb < ptcnt[ly] and not ok;lb++){
- int na = (la+1)%ptcnt[lx];
- int nb = (lb+1)%ptcnt[ly];
- if(check(polys[lx][la], polys[lx][na], polys[ly][lb], polys[ly][nb])){
- //printf("%d %d %d %d\n", la, lb, na, nb);
- ok = true;
- }
- }
- }
- metr[lx][ly] = ok;
- metr[ly][lx] = ok;
- }
- }
- if(n == 1){ puts("1"); continue; }
- for(int lx = 0;lx < n;lx++)
- for(int ly = 0;ly < n;ly++)
- if(metr[lx][ly]){
- //printf("%d -> %d\n", lx, ly);
- to[lx].push_back(ly);
- }
- int min_color = 4;
- for(int _ = 0;_ < 1000;_++){
- for(int lx = 0;lx < n;lx++) col[lx] = -1;
- for(int lx = 0;lx < n;lx++)
- if(col[lx] == -1)
- color(lx);
- int max_c = -1;
- for(int lx = 0;lx < n;lx++) max_c = max(max_c, col[lx]);
- min_color = min(min_color, max_c);
- }
- if(min_color == 4){
- // check 3-cyc
- int cyc3 = 0;
- for(int lx = 0;lx < n;lx++)
- for(int ly = lx+1;ly < n;ly++)
- for(int lz = ly+1;lz < n;lz++)
- cyc3 += metr[lx][ly] and metr[lz][ly] and metr[lx][lz];
- if(cyc3 == 0){puts("3"); continue;}
- }
- printf("%d\n", min_color);
- }
- return 0;
- }
沒有留言:
張貼留言