Tarango

Flyover in Twinland

Aug 2nd, 2016
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.32 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define pb push_back
  5. #define mems(x,v) memset(x,v,sizeof(x))
  6. #define LL long long
  7. #define Size 505
  8. #define INF (1<<30)
  9. int dir4[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
  10.  
  11. struct Edge{
  12.     int u;
  13.     int v;
  14.     LL w;
  15.     LL factor;
  16.     Edge(){
  17.         u = v = w = factor = 0;
  18.     }
  19.     Edge(int a,int b,LL c,LL d){
  20.         u = a;v = b;w = c;factor = d;
  21.     }
  22. };
  23.  
  24. bool cmp(Edge a,Edge b){
  25.     return (a.w<b.w);
  26. }
  27.  
  28. int N,M,V,E;
  29. int clr = 0;
  30.  
  31. LL Mat[Size][Size];
  32. LL color[Size][Size];
  33. bool vis[Size][Size];
  34. int Szz[500000];
  35. int Graph[500000][105];
  36.  
  37. Edge eList[5000000];
  38. int parent[500000];
  39.  
  40. bool isValid(int r,int c){
  41.     if(r<0 || c<0 || r>=N || c>=M) return false;
  42.     return true;
  43. }
  44.  
  45. int DFS1(int r,int c,int id){
  46.     color[r][c] = id;
  47.     vis[r][c] = true;
  48.     int res = 0;
  49.     for(int i = 0;i<4;i++){
  50.         int nr = r + dir4[i][0];
  51.         int nc = c + dir4[i][1];
  52.         if(isValid(nr,nc) == false) continue;
  53.         if(vis[nr][nc] == true) continue;
  54.         if(Mat[nr][nc] == 0) continue;
  55.         res += (DFS1(nr,nc,id) + 1);
  56.     }
  57.     return res;
  58. }
  59.  
  60. /// Color all the islands and count number of cities in those islands:
  61.  
  62. void DFS2(int r,int c,int id){
  63.     Graph[id][Mat[r][c]] = 1;
  64.     vis[r][c] = true;
  65.     for(int i = 0;i<4;i++){
  66.         int nr = r + dir4[i][0];
  67.         int nc = c + dir4[i][1];
  68.         if(isValid(nr,nc) == false) continue;
  69.         if(vis[nr][nc] == true) continue;
  70.         if(Mat[nr][nc] == 0) continue;
  71.         DFS2(nr,nc,id);
  72.     }
  73. }
  74.  
  75. /// Find all the edges and build the graph:
  76.  
  77. void updateGraph(){
  78.     V = E = 0;
  79.     mems(vis,false);
  80.     mems(color,-1);
  81.     int cc = 0;
  82.     for(int i = 0;i<N;i++){
  83.         for(int j = 0;j<M;j++){
  84.             if(vis[i][j] == true) continue;
  85.             if(Mat[i][j] == 0) continue;
  86.             int t = DFS1(i,j,cc) + 1;
  87.             Szz[cc] = t;
  88.             cc++;
  89.         }
  90.     }
  91.     mems(vis,false);
  92.     mems(Graph,0);
  93.     for(int i = 0;i<N;i++){
  94.         for(int j = 0;j<M;j++){
  95.             if(vis[i][j] == true) continue;
  96.             if(Mat[i][j] == 0) continue;
  97.             int cc = color[i][j];
  98.             if(Szz[cc]>=100){
  99.                 DFS2(i,j,V);
  100.                 V++;
  101.             }
  102.         }
  103.     }
  104. }
  105.  
  106. int getParent(int u){
  107.     if(parent[u] == u) return u;
  108.     return parent[u] = getParent(parent[u]);
  109. }
  110.  
  111. /// Minimum spanning tree kruskal algorithm:
  112.  
  113. LL MST(LL factorLimit){
  114.     for(int i = 0;i<V;i++){
  115.         parent[i] = i;
  116.     }
  117.     LL cnt = 0,cost = 0;
  118.     for(int i = 0;i<E;i++){
  119.         Edge e = eList[i];
  120.         if(e.factor > factorLimit) continue;
  121.         int parU = getParent(e.u);
  122.         int parV = getParent(e.v);
  123.         if(parU != parV){
  124.             cnt++;
  125.             cost += e.w;
  126.             parent[parU] = parV;
  127.         }
  128.     }
  129.     if(cnt != V-1) return -1;
  130.     return cost;
  131. }
  132.  
  133. /// Find both salary & construction cost to build a flyover from u to v:
  134.  
  135. pair<LL,LL> getMinimumCost(int u,int v){
  136.     LL prvU = -1,prvV = -1;
  137.     LL rs = INF,w = 0;
  138.     for(int cc = 1;cc<100;cc++){
  139.         if(Graph[u][cc] == 1) prvU = cc;
  140.         if(Graph[v][cc] == 1) prvV = cc;
  141.         if(prvU != -1 && prvV != -1){
  142.             rs = min(rs,abs(prvU - prvV));
  143.         }
  144.         if(Graph[u][cc] == 1 || Graph[v][cc] == 1) w++;
  145.     }
  146.     return make_pair(rs,w*w);
  147. }
  148.  
  149. void solve(){
  150.     updateGraph();
  151.     for(int u = 0;u<V;u++){
  152.         for(int v = u+1;v<V;v++){
  153.             pair<LL,LL> pr = getMinimumCost(u,v);
  154.             eList[E++] = Edge(u,v,pr.first,pr.second);
  155.         }
  156.     }
  157.  
  158.     sort(eList,eList+E,cmp);
  159.     LL L = 0,R = 20000,cnt = 30,M;
  160.     LL resFactor,resCost;
  161.     if(V<=1){
  162.         printf("0 0\n");
  163.         return;
  164.     }
  165.  
  166.     /// Binary search for the maximum salary Rio'll have to pay:
  167.     while(cnt--){
  168.         M = (L+R)/2;
  169.         int cs = MST(M);
  170.         if(cs != -1){
  171.             R = M;
  172.             resFactor = M;
  173.             resCost = cs;
  174.         }else{
  175.             L = M+1;
  176.         }
  177.     }
  178.     printf("%lld %lld\n",resFactor,resCost);
  179. }
  180.  
  181. int main(){
  182.     scanf("%d %d",&N,&M);
  183.     for(int i = 0;i<N;i++){
  184.         for(int j = 0;j<M;j++){
  185.             scanf("%lld",&Mat[i][j]);
  186.         }
  187.     }
  188.     mems(vis,false);
  189.  
  190.     /// First we find all the components:
  191.     DFS1(0,0,0);
  192.     solve();
  193.     return 0;
  194. }
Advertisement
Add Comment
Please, Sign In to add comment