Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <fstream>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #define MAX_VAL 1000000000
- #define MAX_N 101
- using namespace std;
- int n, m,s,t;
- long long max_flow=0,min_cost=0,min_cost_newgraph=0,max_flow_newgraph=0;
- long long d[MAX_N];
- long long p[MAX_N];
- struct arc {//arc-дуга
- int u;
- int v;
- long long c; //пропускная способность
- long long cost;//стоимость единицы пропускной способности
- long long cur_thread;//текущий поток
- arc* obr_vert;//обратная дуга
- arc(int x, int y, long long cc, long long cost_) : u(x), v(y), c(cc), cost(cost_),cur_thread(0) {};
- };
- vector<arc*> res;
- arc* path[MAX_N];
- vector<arc*> graph[MAX_N],newgraph[MAX_N];
- void init() {
- for (int i = 0; i < n; i++) {
- d[i] = 0;
- path[i] = 0;
- }
- }
- //functions for graph
- long long bfs_graph(int s, int t) {
- queue<int> q;
- arc* path[MAX_N];
- for (int i = 0; i < n; i++)
- path[i] = 0;
- q.push(s);
- long long count_thread = MAX_N;
- while (!q.empty()) {
- int v = q.front();
- q.pop();
- if (v == t) {
- res.clear();
- while (v != s) {
- res.push_back(path[v]);
- count_thread = min(count_thread, path[v]->c - path[v]->cur_thread);
- v = path[v]->u;
- }
- for (arc* vert : res) {
- vert->cur_thread += count_thread;
- vert->obr_vert->cur_thread -= count_thread;
- }
- return count_thread;
- }
- for (int i = 0; i < graph[v].size(); i++) {
- arc* vert = graph[v][i];
- if (!path[vert->v] && vert->c - vert->cur_thread > 0) {
- path[vert->v] = vert;
- q.push(vert->v);
- }
- }
- }
- return 0;
- }
- void max_flow_ff_graph(){
- long long add = bfs_graph(s, t);
- while (add){
- max_flow += add;
- add = bfs_graph(s, t);
- }
- }
- bool negative_cycle_graph() {
- init();
- int flow;
- arc* vert;
- for (int z = 0; z < n; z++) {
- flow = -1;
- for (int i = 0; i < n; i++)
- for (int j = 0; j < graph[i].size(); j++) {
- vert = graph[i][j];
- if (d[vert->v] > d[vert->u] + vert->cost && vert->c - vert->cur_thread > 0) {
- d[vert->v] = max(d[vert->u] + vert->cost, -(long long)MAX_VAL);
- path[vert->v] = vert;
- flow = vert->v;
- }
- }
- }
- res.clear();
- if (flow != -1) {
- int y = flow;
- long long add = MAX_VAL;
- for (int i = 0; i < n; i++) y = path[y]->u;
- for (int cur = y; ; cur = path[cur]->u) {
- res.push_back(path[cur]);
- if (cur == y && res.size() > 1) break;
- }
- if (res.size() > 0) res.pop_back();
- for (int i = 0; i < res.size(); i++)
- add = min(add, res[i]->c - res[i]->cur_thread);
- for (int i = 0; i < res.size(); i++) {
- res[i]->cur_thread += add;
- res[i]->obr_vert->cur_thread -= add;
- }
- return true;
- }
- return false;
- }
- void no_nevative_cycle_graph() {
- while (negative_cycle_graph()) {}
- }
- void min_cost_flow_graph() {
- no_nevative_cycle_graph();
- for (int i = 0; i < n; i++)
- for (int j = 0; j < graph[i].size(); j++)
- if (graph[i][j]->cur_thread > 0)
- min_cost += graph[i][j]->cost * graph[i][j]->cur_thread;
- }
- //functions for new graph
- long long bfs_newgraph(int s, int t) {
- queue<int> q;
- arc* path[MAX_N];
- for (int i = 0; i < n; i++)
- path[i] = 0;
- q.push(s);
- long long count_thread = MAX_N;
- while (!q.empty()) {
- int v = q.front();
- q.pop();
- if (v == t) {
- res.clear();
- while (v != s) {
- res.push_back(path[v]);
- count_thread = min(count_thread, path[v]->c - path[v]->cur_thread);
- v = path[v]->u;
- }
- for (arc* vert : res) {
- vert->cur_thread += count_thread;
- vert->obr_vert->cur_thread -= count_thread;
- }
- return count_thread;
- }
- for (int i = 0; i < newgraph[v].size(); i++) {
- arc* vert = newgraph[v][i];
- if (!path[vert->v] && vert->c - vert->cur_thread > 0) {
- path[vert->v] = vert;
- q.push(vert->v);
- }
- }
- }
- return 0;
- }
- void max_flow_ff_newgraph() {
- long long add = bfs_newgraph(s, t);
- while (add) {
- max_flow_newgraph += add;
- add = bfs_newgraph(s, t);
- }
- }
- bool negative_cycle_newgraph() {
- init();
- int flow;
- arc* vert;
- for (int z = 0; z < n; z++) {
- flow = -1;
- for (int i = 0; i < n; i++)
- for (int j = 0; j < newgraph[i].size(); j++) {
- vert = newgraph[i][j];
- if (d[vert->v] > d[vert->u] + vert->cost && vert->c - vert->cur_thread > 0) {
- d[vert->v] = max(d[vert->u] + vert->cost, -(long long)MAX_VAL);
- path[vert->v] = vert;
- flow = vert->v;
- }
- }
- }
- res.clear();
- if (flow != -1) {
- int y = flow;
- long long add = MAX_VAL;
- for (int i = 0; i < n; i++)
- y = path[y]->u;
- for (int cur = y; ; cur = path[cur]->u) {
- res.push_back(path[cur]);
- if (cur == y && res.size() > 1) break;
- }
- if (res.size() > 0)
- res.pop_back();
- for (int i = 0; i < res.size(); i++)
- add = min(add, res[i]->c - res[i]->cur_thread);
- for (int i = 0; i < res.size(); i++) {
- res[i]->cur_thread += add;
- res[i]->obr_vert->cur_thread -= add;
- }
- return true;
- }
- return false;
- }
- void no_nevative_cycle_newgraph() {
- while (negative_cycle_newgraph()) {}
- }
- void min_cost_flow_newgraph() {
- no_nevative_cycle_newgraph();
- for (int i = 0; i < n; i++)
- for (int j = 0; j < newgraph[i].size(); j++)
- if (newgraph[i][j]->cur_thread > 0)
- min_cost_newgraph += newgraph[i][j]->cost * newgraph[i][j]->cur_thread;
- }
- int main() {
- FILE* in = fopen("input.txt", "rt");
- FILE* out = fopen("output.txt", "wt");
- fscanf(in, "%d", &n);
- fscanf(in, "%d", &m);
- fscanf(in, "%d", &s);
- fscanf(in, "%d", &t);
- s--;
- t--;
- int x = 0, y = 0, c = 0, cost=0;
- for (int i = 0; i < m; i++) {
- fscanf(in, "%d %d %d %d", &x, &y, &c, &cost);
- arc* x1 = new arc(x - 1, y - 1, c, cost);
- arc* x2 = new arc(y - 1, x - 1, 0, -cost);
- graph[x - 1].push_back(x1);
- graph[y - 1].push_back(x2);
- x1->obr_vert = x2;
- x2->obr_vert = x1;
- }
- max_flow_ff_graph();
- min_cost_flow_graph();
- long long matr[MAX_N][MAX_N];
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n; j++) {
- matr[i][j] = 0;
- }
- }
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < graph[i].size(); j++) {
- graph[i][j]->cur_thread = 0;
- }
- }
- while (!feof(in)) {
- fscanf(in, "%d %d", &x, &y);
- x--;
- y--;
- matr[x][y] = 1;
- matr[y][x] = 1;
- }
- for (int i = 0; i < n; i++) {
- for (int j = 0; j <graph[i].size(); j++)
- if (matr[i][graph[i][j]->v] == 1 || matr[graph[i][j]->v][i] == 1) {
- newgraph[i].push_back(graph[i][j]);
- }
- }
- max_flow_ff_newgraph();
- min_cost_flow_newgraph();
- if (min_cost != min_cost_newgraph) {
- fprintf(out, "No\n%lld\n%lld\n%lld\n%lld",max_flow,min_cost,max_flow_newgraph,min_cost_newgraph);
- }
- else {
- fprintf(out, "Yes\n%lld\n%lld", max_flow, min_cost);
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement