zoukankan      html  css  js  c++  java
  • [loj3525]喷泉公园

    先将整张图$x$和$y$​都缩小一半,即"道路"长度变为1,"长椅"变为放在格子中心

    如果在没有长椅的限制下也无解(直接dfs即可判定),显然原问题也无解

    否则,将所有格子(注意不是点)黑白染色,并强制横向道路(即从$(x,y)$到$(x+1,y)$的道路,纵向同理)对应的长椅在黑色格子的中心、纵向道路对应的长椅在白色格子的中心

    在这个限制(构造)下,长椅的限制即变为黑(白)色格子的上下(左右)两边不同时为横(纵)向道路

    从上到下、从左到右依次贪心选边(能选即选),简单画图不难发现合法

    为了方便,可以使用map维护,复杂度为$o(nlog n)$

     1 #include<bits/stdc++.h>
     2 #include"parks.h"
     3 using namespace std;
     4 #define N 200005
     5 #define vi vector<int>
     6 #define pii pair<int,int>
     7 #define mp make_pair
     8 #define fi first
     9 #define se second
    10 int n,id[N],f[N];
    11 pii a[N];
    12 vi ansu,ansv,ansa,ansb;
    13 map<int,int>mat[N],vis[N];
    14 bool cmp(int x,int y){
    15     return a[x]<a[y];
    16 }
    17 int find(int k){
    18     if (k==f[k])return k;
    19     return f[k]=find(f[k]);
    20 }
    21 void add(int x,int y,pii z){
    22     vis[z.fi][z.se]=1;
    23     f[find(x)]=find(y);
    24     ansu.push_back(x-1);
    25     ansv.push_back(y-1);
    26     ansa.push_back(z.fi*2+1);
    27     ansb.push_back(z.se*2+1);
    28 }
    29 int construct_roads(vi x,vi y){
    30     n=x.size();
    31     for(int i=1;i<=n;i++){
    32         a[i]=mp(x[i-1]/2,y[i-1]/2);
    33         id[i]=f[i]=mat[a[i].fi][a[i].se]=i;
    34     }
    35     sort(id+1,id+n+1,cmp);
    36     for(int j=1;j<=n;j++){
    37         int i=id[j],k=mat[a[i].fi+1][a[i].se];
    38         if ((k)&&(find(i)!=find(k))){
    39             if ((a[i].fi+a[i].se)&1)add(i,k,a[i]);
    40             else{
    41                 if (!vis[a[i].fi][a[i].se-1])add(i,k,mp(a[i].fi,a[i].se-1));
    42             }
    43         }
    44         k=mat[a[i].fi][a[i].se+1];
    45         if ((k)&&(find(i)!=find(k))){
    46             if ((a[i].fi+a[i].se)%2==0)add(i,k,a[i]);
    47             else{
    48                 if (!vis[a[i].fi-1][a[i].se])add(i,k,mp(a[i].fi-1,a[i].se));
    49             }
    50         }
    51     }
    52     for(int i=1;i<=n;i++)
    53         if (find(i)!=find(1))return 0;
    54     build(ansu,ansv,ansa,ansb);
    55     return 1;
    56 } 
    View Code
  • 相关阅读:
    python之路-随笔 python处理excel文件
    eclipse添加注释
    junit单元测试
    【FLEX教程】#008 开发中的问题笔记(慢更…)
    【FLEX教程】#007 如何让JS调用SWF里的方法
    【总结】2014年度总结
    【转】#100 代码运行框
    【实战项目】【FLEX】#900 实现拖控件功能
    【教程】【FLEX】#006 控件位置的拖动
    【教程】【FLEX】#005 拖动
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15063484.html
Copyright © 2011-2022 走看看