Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- in.txt
- 3 4
- -3 3 5
- -2 -2 6
- 2 2 5
- -1 1 3
- 1 1 4
- -2 -2 7
- 0 -1 3
- 3 1 1 0
- 0 0 6 0
- 0 3 0 2
- //последние 3 строки это "план Городского совета"
- #include <iostream>
- #include <cstdio>
- #include <cmath>
- #include <limits>
- #define CLR(a, x) memset( a, x, sizeof( a ) )
- #define Pot(u,v) (d[u] + pi[u] - pi[v])
- const int MAXN = 100;
- const int MAXM = 100;
- const int INF = std::numeric_limits<int>::max();
- int buildings[MAXN][3];
- int shelters[MAXM][3];
- double distance[MAXN + MAXM + 2][MAXN + MAXM + 2];
- int people[MAXN + MAXM + 2][MAXN + MAXM + 2];
- int fnet[MAXN + MAXM + 2][MAXN + MAXM + 2], adj[MAXN + MAXM + 2][MAXN + MAXM + 2], deg[MAXN + MAXM + 2];
- int par[MAXN + MAXM + 2], d[MAXN + MAXM + 2];
- int pi[MAXN + MAXM + 2];
- double dist(int x1, int y1, int x2, int y2) {
- return sqrt((double)(x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
- }
- bool dijkstra( int n, int s, int t )
- {
- for( int i = 0; i < n; i++ ) d[i] = INF, par[i] = -1;
- d[s] = 0;
- par[s] = -n - 1;
- while( 1 )
- {
- // find u with smallest d[u]
- int u = -1, bestD = INF;
- for( int i = 0; i < n; i++ ) if( par[i] < 0 && d[i] < bestD )
- bestD = d[u = i];
- if( bestD == INF ) break;
- // relax edge (u,i) or (i,u) for all i;
- par[u] = -par[u] - 1;
- for( int i = 0; i < deg[u]; i++ )
- {
- // try undoing edge v->u
- int v = adj[u][i];
- if( par[v] >= 0 ) continue;
- if( fnet[v][u] && d[v] > Pot(u,v) - distance[v][u] )
- d[v] = Pot( u, v ) - distance[v][u], par[v] = -u-1;
- // try edge u->v
- if( fnet[u][v] < people[u][v] && d[v] > Pot(u,v) + distance[u][v] )
- d[v] = Pot(u,v) + distance[u][v], par[v] = -u - 1;
- }
- }
- for( int i = 0; i < n; i++ ) if( pi[i] < INF) pi[i] += d[i];
- return par[t] >= 0;
- }
- int mcmf3( int n, int s, int t, int &fcost )
- {
- // build the adjacency list
- CLR( deg, 0 );
- for( int i = 0; i < n; i++ )
- for( int j = 0; j < n; j++ )
- if( people[i][j] || people[j][i] ) adj[i][deg[i]++] = j;
- CLR( fnet, 0 );
- CLR( pi, 0 );
- int flow = fcost = 0;
- // repeatedly, find a cheapest path from s to t
- while( dijkstra( n, s, t ) )
- {
- // get the bottleneck capacity
- int bot = INT_MAX;
- for( int v = t, u = par[v]; v != s; u = par[v = u] )
- bot <= fnet[v][u] ? fnet[v][u] : ( people[u][v] - fnet[u][v] );
- // update the flow network
- for( int v = t, u = par[v]; v != s; u = par[v = u] )
- if( fnet[v][u] ) { fnet[v][u] -= bot; fcost -= bot * distance[v][u]; }
- else { fnet[u][v] += bot; fcost += bot * distance[u][v]; }
- flow += bot;
- }
- return flow;
- }
- int main() {
- freopen("in.txt", "r", stdin);
- freopen("out.txt", "w", stdout);
- int n, m; std::cin >> n >> m;
- for (int i = 0; i < n; i++)
- for (int j = 0; j < 3; j++)
- std::cin >> buildings[i][j];
- for (int i = 0; i < m; i++)
- for (int j = 0; j < 3; j++)
- std::cin >> shelters[i][j];
- for (int i = 0; i < m + n + 2; i++)
- for (int j = 0; j < m + n + 2; j++)
- distance[i][j] = 0;
- for (int i = 1; i <= n; i++)
- for (int j = 1; j <= m; j++)
- distance[i][j] = dist(buildings[i][0], buildings[i][1], shelters[j][0], shelters[j][1]);
- for (int i = 0; i < m + n + 2; i++)
- for (int j = 0; j < m + n + 2; j++)
- people[i][j] = INF;
- for (int i = 1; i <= n; i++)
- people[0][i] = buildings[i - 1][2];
- for (int j = n + 1; j < n + m + 1; j++)
- people[j][m + n + 1] = shelters[j - n - 1][2];
- int fcost;
- std::cout << mcmf3(n + m + 2, 0, n + m + 1, fcost) << "\n";
- std::cout << fcost << "\n";
- for ( int i = 0; i < n + m + 2; i++) {
- for (int j = 0; j < n + m + 2; j++)
- std::cout << fnet[i][j] << " ";
- std::cout << "\n";
- }
- }
Add Comment
Please, Sign In to add comment