原题链接: 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;
}
本文详细解析了Codeforces上一道E级别的题目,采用二分法结合二分图判断的策略解决点数量较多的问题,避免使用邻接表而采用邻接矩阵存储。文章分享了解题思路,包括如何通过两轮二分查找解决第一问和第二问,同时提供了完整的代码实现。

被折叠的 条评论
为什么被折叠?



