Guest User

Untitled

a guest
Jul 19th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. in.txt
  2. 3 4
  3. -3 3 5
  4. -2 -2 6
  5. 2 2 5
  6. -1 1 3
  7. 1 1 4
  8. -2 -2 7
  9. 0 -1 3
  10. 3 1 1 0
  11. 0 0 6 0
  12. 0 3 0 2
  13.  
  14. //последние 3 строки это "план Городского совета"
  15.  
  16. #include <iostream>
  17. #include <cstdio>
  18. #include <cmath>
  19. #include <limits>
  20.  
  21. #define CLR(a, x) memset( a, x, sizeof( a ) )
  22. #define Pot(u,v) (d[u] + pi[u] - pi[v])
  23.  
  24.  
  25. const int MAXN = 100;
  26. const int MAXM = 100;
  27. const int INF = std::numeric_limits<int>::max();
  28.  
  29. int buildings[MAXN][3];
  30. int shelters[MAXM][3];
  31. double distance[MAXN + MAXM + 2][MAXN + MAXM + 2];
  32. int people[MAXN + MAXM + 2][MAXN + MAXM + 2];
  33.  
  34. int fnet[MAXN + MAXM + 2][MAXN + MAXM + 2], adj[MAXN + MAXM + 2][MAXN + MAXM + 2], deg[MAXN + MAXM + 2];
  35. int par[MAXN + MAXM + 2], d[MAXN + MAXM + 2];
  36. int pi[MAXN + MAXM + 2];
  37.  
  38. double dist(int x1, int y1, int x2, int y2) {
  39.     return sqrt((double)(x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
  40. }
  41.  
  42. bool dijkstra( int n, int s, int t )
  43. {
  44.     for( int i = 0; i < n; i++ ) d[i] = INF, par[i] = -1;
  45.     d[s] = 0;
  46.     par[s] = -n - 1;
  47.  
  48.     while( 1 )
  49.     {
  50.         // find u with smallest d[u]
  51.         int u = -1, bestD = INF;
  52.         for( int i = 0; i < n; i++ ) if( par[i] < 0 && d[i] < bestD )
  53.             bestD = d[u = i];
  54.         if( bestD == INF ) break;
  55.  
  56.         // relax edge (u,i) or (i,u) for all i;
  57.         par[u] = -par[u] - 1;
  58.         for( int i = 0; i < deg[u]; i++ )
  59.         {
  60.             // try undoing edge v->u      
  61.             int v = adj[u][i];
  62.             if( par[v] >= 0 ) continue;
  63.             if( fnet[v][u] && d[v] > Pot(u,v) - distance[v][u] )
  64.                 d[v] = Pot( u, v ) - distance[v][u], par[v] = -u-1;
  65.        
  66.             // try edge u->v
  67.             if( fnet[u][v] < people[u][v] && d[v] > Pot(u,v) + distance[u][v] )
  68.                 d[v] = Pot(u,v) + distance[u][v], par[v] = -u - 1;
  69.         }
  70.     }
  71.  
  72.     for( int i = 0; i < n; i++ ) if( pi[i] < INF) pi[i] += d[i];
  73.  
  74.     return par[t] >= 0;
  75. }
  76.  
  77. int mcmf3( int n, int s, int t, int &fcost )
  78. {
  79.     // build the adjacency list
  80.     CLR( deg, 0 );
  81.     for( int i = 0; i < n; i++ )
  82.     for( int j = 0; j < n; j++ )
  83.         if( people[i][j] || people[j][i] ) adj[i][deg[i]++] = j;
  84.        
  85.     CLR( fnet, 0 );
  86.     CLR( pi, 0 );
  87.     int flow = fcost = 0;
  88.    
  89.     // repeatedly, find a cheapest path from s to t
  90.     while( dijkstra( n, s, t ) )
  91.     {
  92.         // get the bottleneck capacity
  93.         int bot = INT_MAX;
  94.         for( int v = t, u = par[v]; v != s; u = par[v = u] )
  95.             bot <= fnet[v][u] ? fnet[v][u] : ( people[u][v] - fnet[u][v] );
  96.  
  97.         // update the flow network
  98.         for( int v = t, u = par[v]; v != s; u = par[v = u] )
  99.             if( fnet[v][u] ) { fnet[v][u] -= bot; fcost -= bot * distance[v][u]; }
  100.             else { fnet[u][v] += bot; fcost += bot * distance[u][v]; }
  101.    
  102.         flow += bot;
  103.     }
  104.  
  105.     return flow;
  106. }
  107.  
  108. int main() {
  109.     freopen("in.txt", "r", stdin);
  110.     freopen("out.txt", "w", stdout);
  111.     int n, m; std::cin >> n >> m;
  112.     for (int i = 0; i < n; i++)
  113.         for (int j = 0; j < 3; j++)
  114.             std::cin >> buildings[i][j];
  115.     for (int i = 0; i < m; i++)
  116.         for (int j = 0; j < 3; j++)
  117.             std::cin >> shelters[i][j];
  118.     for (int i = 0; i < m + n + 2; i++)
  119.         for (int j = 0; j < m + n + 2; j++)
  120.             distance[i][j] = 0;
  121.     for (int i = 1; i <= n; i++)
  122.         for (int j = 1; j <= m; j++)
  123.             distance[i][j] = dist(buildings[i][0], buildings[i][1], shelters[j][0], shelters[j][1]);
  124.     for (int i = 0; i < m + n + 2; i++)
  125.         for (int j = 0; j < m + n + 2; j++)
  126.             people[i][j] = INF;
  127.     for (int i = 1; i <= n; i++)
  128.         people[0][i] = buildings[i - 1][2];
  129.     for (int j = n + 1; j < n + m + 1; j++)
  130.         people[j][m + n + 1] = shelters[j - n - 1][2];
  131.     int fcost;
  132.     std::cout << mcmf3(n + m + 2, 0, n + m + 1, fcost) << "\n";
  133.     std::cout << fcost << "\n";
  134.     for ( int i = 0; i < n + m + 2; i++) {
  135.         for (int j = 0; j < n + m + 2; j++)
  136.             std::cout << fnet[i][j] << " ";
  137.         std::cout << "\n";
  138.     }
  139. }
Add Comment
Please, Sign In to add comment