CodeForces - 85E 二分+二分图
原题链接: 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; }