• [loj3274]变色龙之恋


    首先有一个暴力的做法,将任意两个点判断,可以得到与之相关的1或3只变色龙:1只是两只变色龙相互喜欢,那么剩下那只就是颜色相同;3只从3只选2只并和自己判断一次,结果为1的那次剩下的那个就是他喜欢的,然后将所有喜欢关系删掉后剩下的就是颜色相同
    但这样一开始需要$o(n^2)$次的判断,考虑优化,如果将点划分成若干个集合,每一个集合内部没有特殊关系就可行了,然后就可以再集合中二分来查找了,那么直接对前i-1个点构成的图染成2种颜色(4种颜色容易超过次数),分别进行二分查找即可,次数是$o(nlogn)$的,常数要注意(4种颜色的要注意要取编号最小的颜色,不然会被卡)

     1 #include "chameleon.h"
     2 #include <bits/stdc++.h>
     3 using namespace std;
     4 #define N 1005
     5 vector<int>v,p[11],vec[N];
     6 int vis[N],to[N],ans[N][2];
     7 bool pd(vector<int> &k,int l,int r,int x){
     8     p[4].clear();
     9     p[4].push_back(x);
    10     for(int i=l;i<=r;i++)p[4].push_back(k[i]);
    11     return Query(p[4])<p[4].size();
    12 }
    13 void find(vector<int> &a,int l,int r,int i){
    14     int rr=r;
    15     while (1){
    16         r=rr;
    17         if ((vec[i].size()==3)||(!pd(a,l,r,i)))return;
    18         while (l<r){
    19             int mid=(l+r>>1);
    20             if (pd(a,l,mid,i))r=mid;
    21             else l=mid+1;
    22         }
    23         vec[i].push_back(a[l]);
    24         vec[a[l]].push_back(i);
    25         l++;
    26     }
    27 }
    28 void Solve(int n){
    29     n*=2;
    30     for(int i=1;i<=n;i++){
    31         int flag=4;
    32         for(int j=0;j<4;j++)
    33             if ((vec[i].size()==3)||(!pd(p[j],0,p[j].size()-1,i)))flag=min(flag,j);
    34             else find(p[j],0,p[j].size()-1,i);
    35         p[flag].push_back(i);
    36     }
    37     int t=0;
    38     for(int i=1;i<=n;i++){
    39         if (vec[i].size()<3)continue;
    40         vis[i]=1;
    41         for(int j=0;j<2;j++)
    42             for(int k=j+1;k<3;k++){
    43                 v.clear();
    44                 v.push_back(i);
    45                 v.push_back(vec[i][j]);
    46                 v.push_back(vec[i][k]);
    47                 if (Query(v)==1){
    48                     to[i]=vec[i][3-j-k];
    49                     j=k=3;
    50                 }
    51             }
    52         if (!to[i])to[i]=vec[i][0];
    53     }
    54     for(int i=1;i<=n;i++)
    55         if (vis[i]){
    56             for(int j=0;j<3;j++)
    57                 if (vec[i][j]==to[i])vec[i][j]=0;
    58             for(int j=0;j<3;j++)
    59                 if (vec[to[i]][j]==i)vec[to[i]][j]=0;
    60         }
    61     for(int i=1;i<=n;i++)
    62         if (vis[i])
    63             for(int j=0;j<3;j++)
    64                 if ((vec[i][j])&&(vec[i][j]<i)&&(vec[vec[i][j]].size()==3)){
    65                     ans[++t][0]=i;
    66                     ans[t][1]=vec[i][j];
    67                 }
    68     for(int i=1;i<=n;i++)
    69         if (vec[i].size()==1){
    70             if ((vec[vec[i][0]].size()==1)&&(i>vec[i][0]))continue;
    71             ans[++t][0]=i;
    72             ans[t][1]=vec[i][0];
    73         }
    74     for(int i=1;i<=n/2;i++)Answer(ans[i][0],ans[i][1]);
    75 }
    View Code
  • 相关阅读:
    洛谷 P3366 【模板】最小生成树
    libfreenect
    openni2 和opencv读取数据
    kinect数据读取
    kinect for windows sdk
    caffe android lib
    Hlsl2glsl
    手势识别半自动标注结果视频
    CLM
    10位算法大师
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12575202.html
Copyright © 2020-2023  润新知