-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path6808.cpp
More file actions
136 lines (127 loc) · 3.39 KB
/
6808.cpp
File metadata and controls
136 lines (127 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int MAXN = 1e6+5;
const long long INF = 1LL<<60;
struct Dinic { //O(VVE), with minimum cut
static const int MAXN = 200003;
struct Edge{
int u, v;
long long cap, rest;
};
int n, m, s, t, d[MAXN], cur[MAXN];
vector<Edge> edges;
vector<int> G[MAXN];
void init(){
edges.clear();
for ( int i = 0 ; i < n ; i++ ) G[i].clear();
n = 0;
}
// min cut start
bool side[MAXN];
void cut(int u) {
side[u] = 1;
for ( int i : G[u] ) {
if ( !side[ edges[i].v ] && edges[i].rest ) cut(edges[i].v);
}
}
// min cut end
int add_node(){
return n++;
}
void add_edge(int u, int v, long long cap){
edges.push_back( {u, v, cap, cap} );
edges.push_back( {v, u, 0, 0LL} );
m = edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
bool bfs(){
fill(d,d+n,-1);
queue<int> que;
que.push(s); d[s]=0;
while (!que.empty()){
int u = que.front(); que.pop();
for (int ei : G[u]){
Edge &e = edges[ei];
if (d[e.v] < 0 && e.rest > 0){
d[e.v] = d[u] + 1;
que.push(e.v);
}
}
}
return d[t] >= 0;
}
long long dfs(int u, long long a){
if ( u == t || a == 0 ) return a;
long long flow = 0, f;
for ( int &i=cur[u]; i < (int)G[u].size() ; i++ ) {
Edge &e = edges[ G[u][i] ];
if ( d[u] + 1 != d[e.v] ) continue;
f = dfs(e.v, min(a, e.rest) );
if ( f > 0 ) {
e.rest -= f;
edges[ G[u][i]^1 ].rest += f;
flow += f;
a -= f;
if ( a == 0 )break;
}
}
return flow;
}
long long maxflow(int _s, int _t){
s = _s, t = _t;
long long flow = 0, mf;
while ( bfs() ){
fill(cur,cur+n,0);
while ( (mf = dfs(s, INF)) ) flow += mf;
}
return flow;
}
} dinic;
void go() {
int n;
vector<int>add,minus;
vector<pair<int,int>>v;
cin >> n;
for (int i = 0; i < n; i++) {
int x, y;
cin >> x >> y;
add.push_back(x + y);
minus.push_back(x - y);
v.push_back({x, y});
}
sort((add).begin(), (add).end());
sort((minus).begin(), (minus).end());
add.erase(unique((add).begin(), (add).end()),add.end());
minus.erase(unique((minus).begin(), (minus).end()),minus.end());
dinic.init();
dinic.n = add.size() + minus.size() + 2;
int st = dinic.n - 1;
int ed = st - 1;
for (int i = 0; i < (int)add.size(); i++) {
dinic.add_edge(st,i,1);
}
for (int i = 0; i < (int)minus.size(); i++) {
dinic.add_edge(add.size()+i,ed,1);
}
for (int i = 0; i < n; i++) {
dinic.add_edge(lower_bound((add).begin(), (add).end(),v[i].first + v[i].second) - add.begin(), add.size() + lower_bound((minus).begin(), (minus).end(),v[i].first - v[i].second)-minus.begin(),1);
}
cout << dinic.maxflow(st, ed) << '\n';
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int c = 1;
int t;
if (!c) {
t = 1;
}
else {
cin >> t;
}
while (t--) {
go();
}
}