Guest User

Untitled

a guest
May 23rd, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.00 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <set>
  5. using namespace std;
  6.  
  7. long long n,m;
  8. vector <vector <int> > G;
  9. vector <pair<int,int> > M;
  10.  
  11. int dsu_parent[5000];
  12. int dsu_rank[5000];
  13. int size_of_component[5000];
  14. int edges_of_component[5000];
  15. set <int> all_components;
  16. long long C[5001][5001];
  17. long long answer_one=0,answer_two=0,answer_three=0,answer_four=0;
  18. long long real_answer=0;
  19. int MAXN=5000;
  20.  
  21. ostream & operator<<(ostream &stream, vector <int> &A){
  22.     for (int i=0;i<A.size();i++)
  23.         cout<<A[i]<<" ";
  24.     return stream;
  25. }
  26.  
  27. int dsu_make(int i){
  28.     dsu_parent[i]=i;
  29.     dsu_rank[i]=0;
  30. }
  31.  
  32. void pascal_init(){
  33.     for (int i=0;i<=n;i++)
  34.         C[i][i]=1,C[i][1]=i;
  35.     for (int i=2;i<=n;i++)
  36.     for (int j=2;j<=n-1;j++){
  37.         C[i][j]=C[i-1][j-1]+C[i-1][j];
  38.         //cout<<C[i][j]<<" "<<endl;
  39.     }
  40.     real_answer=C[n][1]+C[n][2]+C[n][3]+C[n][4];
  41. }
  42.  
  43. int dsu_find(int i){
  44.     if (i==dsu_parent[i])
  45.         return i;
  46.     return dsu_parent[i]=dsu_find(dsu_parent[i]);
  47. }
  48.  
  49. void dsu_unite(int a, int b){
  50.     a=dsu_find(a);
  51.     b=dsu_find(b);
  52.     if (a!=b){
  53.         if (dsu_rank[a]<dsu_rank[b])
  54.             swap(a,b);
  55.         dsu_parent[b]=a;
  56.         size_of_component[a]+=size_of_component[b];
  57.         edges_of_component[a]+=edges_of_component[b];
  58.         all_components.erase(b);
  59.         if (dsu_rank[a]==dsu_rank[b])
  60.             dsu_rank[a]++;
  61.     }
  62. }
  63.  
  64. void iterat_for_three(int numb){
  65.     //cout<<"ENTEROFTHREE"<<endl;
  66.     int u=M[numb].first; int v=M[numb].second;
  67.     long long k1=G[u].size();
  68.     long long k2=G[v].size();
  69.     sort (G[u].begin(),G[u].end());
  70.     sort (G[v].begin(),G[v].end());
  71.     vector<int> intersect_of_lists(G[u].size()+G[v].size());
  72.     vector<int>::iterator ite=set_intersection(G[u].begin(),G[u].end(),G[v].begin(),G[v].end(),intersect_of_lists.begin());
  73.     long long e=ite-intersect_of_lists.begin();
  74.     long long answer=(n-2)-k1-k2+e;
  75.     answer_three+=answer;
  76.     //cout<<"EXITOFTHREE"<<endl;
  77. }
  78.  
  79. void iterat_for_four(int numb){
  80.     //cout<<"ENTER:"<<endl;
  81.     int u=M[numb].first; int v=M[numb].second;
  82.     int u_comp=dsu_find(u); int v_comp=dsu_find(v);
  83.     long long k1=G[u].size();
  84.     long long k2=G[v].size();
  85.     long long answer=0;
  86.     long long k=all_components.size();
  87.     long long sums[5000];
  88.     long long local_sizes[5000];
  89.     for (int j=0;j<5000;j++)
  90.         sums[j]=0,local_sizes[j]=0;
  91.     int i=0;
  92.     for (set<int>::iterator it=all_components.begin();it!=all_components.end();it++,i++){
  93.         int cur_comp=*it;
  94.         if (i) sums[i]+=sums[i-1];
  95.         if (cur_comp!=u_comp && cur_comp!=v_comp){
  96.             sums[i]+=size_of_component[cur_comp];
  97.             local_sizes[i]=size_of_component[cur_comp];
  98.             int socp=size_of_component[cur_comp];
  99.             answer+=(socp*(socp-1))/2-edges_of_component[cur_comp];
  100.         }
  101.     }
  102.     //cout<<"POINT1:"<<answer<<endl;
  103.     for (int i=0;i<k;i++){
  104.         long long chast_sum=sums[k-1];
  105.         chast_sum-=sums[i];
  106.         //cout<<local_sizes[i]<<" ";
  107.         answer+=local_sizes[i]*chast_sum;
  108.     }
  109.     //cout<<"POINT2:"<<answer<<endl;
  110.     if (u_comp!=v_comp){
  111.         long long dob=0;
  112.         long long socp=size_of_component[u_comp];
  113.         dob+=((socp-1-G[u].size())*(socp-2-G[u].size()))/2-(edges_of_component[u_comp]-G[u].size());
  114.         socp=size_of_component[v_comp];
  115.         dob+=((socp-1-G[v].size())*(socp-2-G[v].size()))/2-(edges_of_component[v_comp]-G[v].size());
  116.         dob+=(size_of_component[u_comp]-1-G[u].size())*(size_of_component[v_comp]-1-G[v].size());
  117.         for (int i=0;i<k;i++){
  118.             //cout<<"i:"<<i<<" "<<local_sizes[i]<<" "<<size_of_component[u_comp]<<endl;
  119.             answer+=(size_of_component[u_comp]-1-G[u].size())*local_sizes[i];
  120.         }
  121.         //cout<<"POINT2.7:"<<answer<<endl;
  122.         for (int i=0;i<k;i++){
  123.             answer+=(size_of_component[v_comp]-1-G[v].size())*local_sizes[i];
  124.         }
  125.         //cout<<"POINT3:"<<answer<<endl;
  126.     }
  127.     else{
  128.         //cout<<"POINT4:"<<answer<<endl;
  129.        
  130.         sort (G[u].begin(),G[u].end());
  131.         sort (G[v].begin(),G[v].end());
  132.         vector<int> intersect_of_lists(G[u].size()+G[v].size());
  133.         vector<int>::iterator ite=set_intersection(G[u].begin(),G[u].end(),G[v].begin(),G[v].end(),intersect_of_lists.begin());
  134.         intersect_of_lists.resize(ite-intersect_of_lists.begin());
  135.         long long e=ite-intersect_of_lists.begin();
  136.        
  137.         int nn=size_of_component[u_comp];
  138.        
  139.         bool its_not_used[5000];
  140.         its_not_used[u]=true; its_not_used[v]=true;
  141.        
  142.         for (int i=0;i<G[u].size();i++){
  143.             its_not_used[G[u][i]]=true;
  144.         }
  145.         for (int i=0;i<G[v].size();i++){
  146.             its_not_used[G[v][i]]=true;
  147.         }
  148.        
  149.         int unrated_edges=0;
  150.         for (int i=0;i<G[v].size();i++)
  151.         for (int j=0;j<G[G[v][i]].size();j++){
  152.             int to=G[G[v][i]][j];
  153.             //cout<<"TO:"<<to+1<<endl;
  154.             if (its_not_used[to])
  155.                 unrated_edges++;
  156.         }
  157.         for (int i=0;i<G[u].size();i++)
  158.         for (int j=0;j<G[G[u][i]].size();j++){
  159.             int to=G[G[u][i]][j];
  160.             //cout<<"TO:"<<to+1<<endl;
  161.             if (its_not_used[to])
  162.                 unrated_edges++;
  163.         }
  164.         for (int i=0;i<intersect_of_lists.size();i++)
  165.         for (int j=0;j<G[intersect_of_lists[i]].size();j++){
  166.             int to=G[intersect_of_lists[i]][j];
  167.             //cout<<"TO:"<<to+1<<endl;
  168.             if (its_not_used[to])
  169.                 unrated_edges--;
  170.         }
  171.         unrated_edges+=k1+k2;      
  172.         //cout<<unrated_edges<<endl;
  173.         unrated_edges/=2;
  174.         int k1=int(G[u].size());
  175.         int k2=int(G[v].size());
  176.         long long dob=(nn-3-k1-k2+e>=0 ? (nn-2-k1-k2+e)*(nn-3-k1-k2+e) : 0)-(edges_of_component[u_comp]-unrated_edges);
  177.         if (dob<0) dob=0;
  178.         answer+=dob;
  179.         //cout<<"POINT5:"<<answer<<endl;
  180.         for (int i=0;i<k;i++){
  181.             answer+=(nn-2>=0 ? (nn-2-k1-k2+e) : 0)*local_sizes[i];
  182.         }
  183.         //cout<<"POINT6:"<<answer<<endl;
  184.     }
  185.     answer_four+=answer;
  186.     dsu_unite(u,v);
  187.     u_comp=dsu_find(u);
  188.     G[u].push_back(v);
  189.     G[v].push_back(u);
  190.     edges_of_component[u_comp]++;
  191.     //cout<<"EXIT"<<endl;
  192. }
  193.  
  194. int main(){
  195.     cin>>n>>m;
  196.     G.resize(n);
  197.     M.resize(m);
  198.     answer_one=0; answer_two=m;
  199.     for (int i=0;i<m;i++){
  200.         int a,b; cin>>a>>b;
  201.         a--; b--;
  202.         if (a>b) swap(a,b);
  203.         M[i]=(make_pair(a,b));
  204.     }
  205.     for (int i=0;i<n;i++){
  206.         dsu_make(i);
  207.         size_of_component[i]=1;
  208.         all_components.insert(i);
  209.     }
  210.     for (int i=0;i<m;i++){
  211.         iterat_for_three(i);
  212.         iterat_for_four(i);
  213.     }
  214.     pascal_init();
  215.     //cout<<C[n][4]-answer_four<<" "<<C[n][3]-answer_three<<" "<<real_answer<<endl;
  216.     cout<<real_answer-answer_one-answer_two-answer_three-answer_four<<endl;
  217.     return 0;
  218. }
Add Comment
Please, Sign In to add comment