一.题意
给定你一些边,和一些询问,问你在这个询问中新加入的这条边能否成为新最小生成树的边。
二.解题思路
直接按边权排序,若碰到新插入的和原来插入的边,则新插入的放在后边。
三.代码实现
#include "bits/stdc++.h"
using namespace std;
const int N = 5e5 + 10;
struct Edge {int a,b,c,d;} e[N];
int f[N],ans[N];
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
void solve()
{
int n,m,k;
cin >> n >> m >> k;
int idx = 0;
for(int i = 1;i <= m;i++) {
int a,b,c;
cin >> a >> b >> c;
e[++idx] = {a,b,c,0};
}
for(int i = 1;i <= k;i++) {
int a,b,c;
cin >> a >> b >> c;
e[++idx] = {a,b,c,i};
}
sort(e + 1,e + 1 + idx,[](Edge &e,Edge &p){
if(e.c < p.c) return true;
if(e.c == p.c) return e.d < p.d;
return false;
});
for(int i = 1;i <= n;i++) f[i] = i;
int cnt = 0;
for(int i = 1;i <= idx;i++) {
if(cnt == n - 1) break;
int a = e[i].a,b = e[i].b,c = e[i].c,d = e[i].d;
int fa = find(a),fb = find(b);
if(fa != fb) {
if(d) {
ans[d] = 1;
continue;
}
f[fa] = fb;
cnt ++;
}
}
for(int i = 1;i <= k;i++) {
if(ans[i]) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
T = 1;
while(T --) {
solve();
}
return 0;
}
一.题意
给定你一些点对,每两对点对的价值为min(abs(x1 - x2),abs(y1 - y2),现在要求我们求这些点对中价值最大的点对的价值是多少?
二.解题思路
先按x排序,然后二分答案,对于每一个二分的值,我们需要找到任意一个x2 - x1 >= mid,并且abs(y2 - y1)>= mid,因此我们可以预处理后缀的最大和最小的y值。
三.代码实现
#include "bits/stdc++.h"
#define PII pair<int,int>
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 10,inf = 0x3f3f3f3f;
int miy[N],mxy[N];
PII a[N];
int n;
bool check(int mid)
{
for(int i = 1;i <= n;i++) {
int idx = lower_bound(a + 1,a + 1 + n,make_pair(a[i].fi + mid,-inf)) - a;
if(a[idx].fi - a[i].fi < mid) return false;
int p1 = abs(mxy[idx] - a[i].se),p2 = abs(miy[idx] - a[i].se);
if(max(p1,p2) >= mid) return true;
}
return false;
}
void solve()
{
cin >> n;
for(int i = 1;i <= n;i++) cin >> a[i].fi >> a[i].se;
sort(a + 1,a + 1 + n);
memset(mxy,-0x3f,sizeof(mxy));
memset(miy,0x3f,sizeof(miy));
int l = 0,r = a[n].fi - a[1].fi;
for(int i = n;i >= 1;i--) {
mxy[i] = max(a[i].se,mxy[i + 1]);
miy[i] = min(a[i].se,miy[i + 1]);
}
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) l = mid + 1;
else r = mid - 1;
}
cout << max(0,l - 1) << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int T;
T = 1;
while(T --) {
solve();
}
return 0;
}