CodeForces

原题链接: https://codeforces.com/problemset/problem/85/E

很板子的一道题,二分+二分图判断。坑点是这道题点的个数比较多,建图的时候不能用临界表来存图,直接用临界矩阵来存就行。这样第一问就解决了。

第二问的话可以发现答案就是2的连通块数次方,对满足答案的limit跑一遍就可以得到。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map> 
#include <stack>
#include <sstream>
#include <set>
#pragma GCC optimize(2)

//#define int long long
#define mm(i,v) memset(i,v,sizeof i);
#define mp(a, b) make_pair(a, b)
#define pi acos(-1)
#define fi first
#define se second
//你冷静一点,确认思路再敲!!! 

using namespace std;
typedef long long ll;
typedef pair<int, int > PII;
priority_queue< PII, vector<PII>, greater<PII> > que;
stringstream ssin; //  ssin << string   while ( ssin >> int)

const int N = 5e3 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
ll n, m, idx, ans, num, cnt;
ll col[N], c[N], d[N][N];

struct node {
    ll x, y;
}list[N];

inline ll read(){
    char c=getchar();ll x=0ll,f=1ll;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

bool dfs(int u, int num, int lim) {
    col[u] = num;
    for (int i = 1; i <= n; ++i) {
        if (i == u || d[u][i] <= lim) continue;
        if (col[i] == -1) {
            if (!dfs(i, 3 - num, lim)) return false;
        } else if (col[i] == col[u]) return false;
    }
    return true;
}

bool check(int lim) {
    mm(col, -1);
    for (int i = 1; i <= n; ++i) {
        if (col[i] == -1) {
            if (!dfs(i, 1, lim)) {
                return false;
            }
        }
    }
    return true;
}

ll quickmod(ll a,ll b,ll c)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
           ans=ans * a % c;//这样写是为了使a*ans和a*a不溢出
        a=a * a % c;
        b>>=1;
    }
    return ans;
}


int main()
{
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        list[i].x = read();
        list[i].y = read();
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            int z = abs(list[i].x - list[j].x) + abs(list[i].y - list[j].y);
            d[i][j] = z;
        }
    }

    int l = 0, r = 10000;
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    cout << l << endl;
    mm(col, -1);
    cnt = 0;
    for (int i = 1; i <= n; ++i) {
        if (col[i] == -1) {
            cnt++;
            dfs(i, 1, l);
        }
    }
    cout << quickmod(2, cnt, mod) << endl;
    // system("pause");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/mwh123/p/13260136.html