#pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; typedef vector<int> vi; typedef double K; constexpr int INF = 0x3f3f3f3f; #define FOR(i, b, e) for(int i = (b); i < (e); i++) #define TRAV(x, a) for(auto &x: (a)) #define SZ(x) ((int)(x).size()) #define PB push_back #define X first #define Y second constexpr int N = 10010; int n, globFlow; int mat[N][N]; int ans[N]; bool vis[N]; vi G[N]; vi path; bool dfs(int v, int dest, int kraw) { vis[v] = true; if(v == dest) { path.PB(v); return true; } TRAV(i, G[v]) { if(!vis[i] && mat[v][i] == kraw && dfs(i, dest, kraw)) { path.PB(v); return true; } } return false; } bool sciezka(int start, int end, int kraw) { FOR(i, 0, n * 2 + 2) vis[i] = false; path.clear(); if(!dfs(start, end, kraw)) return false; FOR(i, 0, SZ(path) - 1) mat[path[i]][path[i + 1]] ^= 1, mat[path[i + 1]][path[i]] ^= 1; return true; } void dodaj(int v) { mat[v * 2 + 1][1] = 1; while(sciezka(0, 1, 1)) globFlow++; } void usun(int v) { mat[v * 2 + 1][1] = 0; if(mat[1][v * 2 + 1] == 0) return; mat[1][v * 2 + 1] = 0; assert(sciezka(0, v * 2 + 1, 0)), globFlow--; while(sciezka(0, 1, 1)) globFlow++; } void solve() { int m, k; cin >> n >> m >> k; FOR(i, 1, n + 1) { G[i * 2].PB(i * 2 + 1), G[i * 2 + 1].PB(i * 2); mat[i * 2][i * 2 + 1] = 1; } FOR(i, 1, k + 1) { G[0].PB(i * 2), G[i * 2].PB(0); mat[0][i * 2] = 1; } FOR(i, k + 1, n + 1) { G[i * 2 + 1].PB(1); } FOR(i, 0, m) { int a, b; cin >> a >> b; mat[a * 2 + 1][b * 2] = 1; G[a * 2 + 1].PB(b * 2), G[b * 2].PB(a * 2 + 1); } FOR(it, 1, k + 1) { int j = k; FOR(i, k + 1, n + 1) { if(j < i) j++, dodaj(i); while(j < n && globFlow < it) j++, dodaj(j); if(globFlow == it) ans[it] += (n - j + 1); usun(i); } } ans[0] = (n - k + 1) * (n - k) / 2; FOR(i, 0, k + 1) cout << ans[i] - ans[i + 1] << '\n'; } int main() { ios::sync_with_stdio(0); cin.tie(0); // int tt; cin >> tt; // FOR(te, 0, tt) { // // cout << "Case #" << te + 1 << ": "; // solve(); // } solve(); return 0; }
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 | #pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; typedef vector<int> vi; typedef double K; constexpr int INF = 0x3f3f3f3f; #define FOR(i, b, e) for(int i = (b); i < (e); i++) #define TRAV(x, a) for(auto &x: (a)) #define SZ(x) ((int)(x).size()) #define PB push_back #define X first #define Y second constexpr int N = 10010; int n, globFlow; int mat[N][N]; int ans[N]; bool vis[N]; vi G[N]; vi path; bool dfs(int v, int dest, int kraw) { vis[v] = true; if(v == dest) { path.PB(v); return true; } TRAV(i, G[v]) { if(!vis[i] && mat[v][i] == kraw && dfs(i, dest, kraw)) { path.PB(v); return true; } } return false; } bool sciezka(int start, int end, int kraw) { FOR(i, 0, n * 2 + 2) vis[i] = false; path.clear(); if(!dfs(start, end, kraw)) return false; FOR(i, 0, SZ(path) - 1) mat[path[i]][path[i + 1]] ^= 1, mat[path[i + 1]][path[i]] ^= 1; return true; } void dodaj(int v) { mat[v * 2 + 1][1] = 1; while(sciezka(0, 1, 1)) globFlow++; } void usun(int v) { mat[v * 2 + 1][1] = 0; if(mat[1][v * 2 + 1] == 0) return; mat[1][v * 2 + 1] = 0; assert(sciezka(0, v * 2 + 1, 0)), globFlow--; while(sciezka(0, 1, 1)) globFlow++; } void solve() { int m, k; cin >> n >> m >> k; FOR(i, 1, n + 1) { G[i * 2].PB(i * 2 + 1), G[i * 2 + 1].PB(i * 2); mat[i * 2][i * 2 + 1] = 1; } FOR(i, 1, k + 1) { G[0].PB(i * 2), G[i * 2].PB(0); mat[0][i * 2] = 1; } FOR(i, k + 1, n + 1) { G[i * 2 + 1].PB(1); } FOR(i, 0, m) { int a, b; cin >> a >> b; mat[a * 2 + 1][b * 2] = 1; G[a * 2 + 1].PB(b * 2), G[b * 2].PB(a * 2 + 1); } FOR(it, 1, k + 1) { int j = k; FOR(i, k + 1, n + 1) { if(j < i) j++, dodaj(i); while(j < n && globFlow < it) j++, dodaj(j); if(globFlow == it) ans[it] += (n - j + 1); usun(i); } } ans[0] = (n - k + 1) * (n - k) / 2; FOR(i, 0, k + 1) cout << ans[i] - ans[i + 1] << '\n'; } int main() { ios::sync_with_stdio(0); cin.tie(0); // int tt; cin >> tt; // FOR(te, 0, tt) { // // cout << "Case #" << te + 1 << ": "; // solve(); // } solve(); return 0; } |