Advertisement
KinDeR___

Untitled

Oct 24th, 2023
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. //#pragma GCC optimize("unroll-loops")
  4. //#pragma GCC optimize("Ofast")
  5. //#pragma GCC optimize("-O3")
  6.  
  7. #define isz(x) int(x.size())
  8. #define all(x) x.begin(),x.end()
  9. #define rall(x) x.rbegin(),x.rend()
  10. #define ll long long
  11. #define pii pair<int,int>
  12. #define fi first
  13. #define se second
  14. #define isz(x) int(x.size())
  15. #define ull unsigned long long
  16. #define vb vector<bool>
  17. #define vvb vector<vb>
  18. #define vvvb vector<vvb>
  19. #define vi vector<int>
  20. #define vll vector<ll>
  21. #define vch vector<char>
  22. #define vvch vector<vch>
  23. #define vvvch vector<vvch>
  24. #define vvi vector<vector<int>>
  25. #define vvvi vector<vvi>
  26. #define vvll vector<vector<ll>>
  27. #define vvvll vector<vvll>
  28. #define vpii vector<pair<int,int>>
  29. #define vvpii vector<vpii>
  30. #define forn(i,n) for(int i=0;i<(int)n;++i)
  31. #define pb push_back
  32.  
  33. using namespace std;
  34.  
  35. const int UNDEF = -1;
  36. const int MOD = 1e9 + 7;
  37. const int INF = 1e9;
  38.  
  39. int main() {
  40. freopen("input.txt", "rt", stdin);
  41. freopen("output.txt", "wt", stdout);
  42.  
  43. int N,M;
  44. cin>>N>>M; // кол-во вершин , кол-во рёбер
  45.  
  46. vvi g(1+N);
  47. for(int i=1;i<=M;++i){ // считываю рёбра
  48. int a,b;
  49. cin>>a>>b;
  50. g[a].pb(b);
  51. g[b].pb(a);
  52. }
  53.  
  54. vi color(1+N,UNDEF); // каждая вершина изначально цвета не имеет UNDEF = -1
  55.  
  56. function<void(int,int,int&,int&)> dfs=[&](int u,int col,int& cnt0,int& cnt1){
  57. color[u]=col;
  58.  
  59. if(col==0) cnt0++;
  60. else cnt1++;
  61.  
  62. for(int to : g[u]){
  63. assert(color[to]==UNDEF || color[to]==1-col);
  64. if(color[to]==UNDEF) dfs(to,1-col,cnt0,cnt1);
  65. }
  66. };
  67.  
  68. vpii a;// a[i] - хранит разбиение i-ой компоненты связности на доли (a[i].fi - кол-во долей цвета 0, a[i].se - кол-во долей цвета 1)
  69. for(int i=1;i<=N;++i){
  70. if(color[i]==UNDEF){ // Запускаюсь из каждой компоненты связности
  71. int cnt0=0,cnt1=0; // кол-во вершин цвета 0(1 доля),кол-во вершин цвета 1 (2 доля)
  72. dfs(i,1,cnt0,cnt1);
  73. a.pb({cnt0,cnt1});
  74. }
  75. }
  76.  
  77. vb dp(1+N,false); // рюкзак dp[i] значит,что можно набрать i вершин в 1 долю конечного двудольного графа
  78. dp[0]=true;
  79.  
  80. for(int i=0;i<isz(a);++i){
  81. for(int j=N;j>=0;--j){
  82. if(a[i].fi<=j) dp[j] = (dp[j] || dp[j-a[i].fi]);
  83. if(a[i].se<=j) dp[j] = (dp[j] || dp[j-a[i].se]);
  84. }
  85. }
  86.  
  87. int best=-1;
  88. for(int i=1;i<=N;++i){ // перебираю варианты конечного двудольного графа,если i-вершин в первой доле ,то N-i во второй
  89. if(dp[i]) best=max(best,i * (N-i));
  90. }
  91.  
  92. cout<<best-M; // ответ
  93.  
  94. return 0;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement