zoukankan      html  css  js  c++  java
  • CF85E Guard Towers(二分答案+二分图)

    题意

    已知 N 座塔的坐标,N≤5000
    把它们分成两组,使得同组内的两座塔的曼哈顿距离最大值最小
    在此前提下求出有多少种分组方案 mod 109+7

    题解

    二分答案 mid
    曼哈顿距离 >mid 的点连边
    判定是否构成二分图
    方案数为 2^最终的二分图连通块数目
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int N=5110;
     9 const int mod=1000000007;
    10 int dis[N][N],n,x[N],y[N],c[N],ans,num; 
    11 long long ksm(long long a,long long x){
    12     long long ans=1;
    13     while(x){
    14         if(x&1){
    15             ans=(ans*a)%mod;
    16         }
    17         x>>=1;
    18         a=(a*a)%mod;
    19     }
    20     return ans;
    21 }
    22 bool dfs(int u,int x,int col){
    23     for(int i=1;i<=n;i++){
    24         if(dis[u][i]>x){
    25             if(c[i]!=-1){
    26                 if(c[i]==col^1)continue;
    27                 if(c[i]==col) return true;
    28             }
    29             c[i]=col^1;
    30             if(dfs(i,x,col^1))return true;
    31         }
    32     }
    33     return false;
    34 }
    35 bool check(int x){
    36 //    cout<<x<<"jsdfhjsdf"<<endl;
    37     memset(c,-1,sizeof(c));
    38     for(int i=1;i<=n;i++){
    39         if(c[i]==-1){
    40             c[i]=1;
    41             if(dfs(i,x,1))return false;
    42         }
    43     }
    44 //    cout<<x<<endl;
    45 //    for(int i=1;i<=n;i++){
    46 //        cout<<c[i]<<" ";
    47 //    }
    48 //    cout<<endl;
    49     return true;
    50 }
    51 void bfs(int u,int col){
    52     queue<int> q;
    53     c[u]=col;
    54     q.push(u);
    55     while(!q.empty()){
    56         int u=q.front();
    57         q.pop();
    58         for(int i=1;i<=n;i++){
    59             if(c[i])continue;
    60             if(dis[i][u]>ans)c[i]=col,q.push(i);
    61         }
    62     } 
    63 }
    64 int main(){
    65     scanf("%d",&n);
    66     for(int i=1;i<=n;i++){
    67         scanf("%d%d",&x[i],&y[i]);
    68     }
    69     for(int i=1;i<=n;i++)    
    70         for(int j=1;j<=n;j++){
    71             dis[i][j]=abs(x[i]-x[j])+abs(y[i]-y[j]);
    72 //            cout<<i<<" "<<j<<" "<<dis[i][j]<<endl; 
    73         } 
    74     int l=0,r=10001;
    75     while(l<=r){
    76         int mid=(l+r)>>1;
    77         if(check(mid)){
    78             ans=mid;
    79             r=mid-1;
    80         }
    81         else l=mid+1;
    82     }
    83     printf("%d
    ",ans);
    84     memset(c,0,sizeof(c));
    85     for(int i=1;i<=n;i++){
    86         if(c[i]==0){
    87             bfs(i,++num);
    88         }
    89     }
    90     printf("%lld",ksm(2,num));
    91 }
    View Code
  • 相关阅读:
    SVG <–> XAML
    Visual Studio 2005 下 ASP.net Web Service SOAP XML 节点的疑惑
    IE 和 Chrome 不能上网,Windows Live Mail 不能发邮件。Firefox可用。解决办法
    c# FileStream和StreamWriter用法
    c# 壓縮與解壓的簡單學習
    c# 文件輸入和輸出主要類說明
    部署Web應用程序
    allowDefinition='MachineToApplication' 错误的解决办法
    Global.asax的16个事件处理过程
    c# 類模板加上自定義內容
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9385907.html
Copyright © 2011-2022 走看看