Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#define _CRT_SECURE_NO_WARNINGS
- //#include <iostream>
- //#include <vector>
- //#include <queue>
- //#include <set>
- //#include <stack>
- //#include <algorithm>
- //
- //using namespace std;
- //
- //int START, END, N;
- //vector <vector <int>> FLOWS;
- //vector <vector <int>> GRAPH;
- //
- //int bfs(int vertex) {
- // queue<pair<int, int>> q;
- // set<int> visited;
- // stack <pair<int, int>> stack_;
- // q.push(make_pair(vertex, -1));
- // while (!q.empty()) {
- // pair<int, int> temp = q.front();
- // q.pop();
- // stack_.push(temp);
- // if (temp.first == END) {
- // break;
- // }
- // for (int i = 0; i < N; i++) {
- // if (visited.find(i) != visited.end()) {
- // continue;
- // }
- // if (GRAPH[temp.first][i] - FLOWS[temp.first][i] > 0) {
- // visited.insert(i);
- // q.push(make_pair(i, temp.first));
- // }
- // }
- // }
- // vector <int> way;
- // int cur = END;
- // while (!stack_.empty()) {
- // auto i = stack_.top();
- // stack_.pop();
- // if (i.first == cur) {
- // cur = i.second;
- // way.push_back(i.first);
- // }
- // }
- // reverse(way.begin(), way.end());
- // if (way.size() == 0) {
- // return -1;
- // }
- //
- // int flow = 10e9;
- //
- // for (int i = 0; i < way.size() - 1; i++) {
- // flow = min(GRAPH[way[i]][way[i + 1]] - FLOWS[way[i]][way[i + 1]], flow);
- // }
- // for (int i = 0; i < way.size() - 1; i++) {
- // FLOWS[way[i]][way[i + 1]] += flow;
- // FLOWS[way[i + 1]][way[i]] -= flow;
- // }
- // return flow;
- //}
- //
- //int main() {
- // freopen("input.txt", "r", stdin);
- // freopen("output.txt", "w", stdout);
- // N;
- // int MAXFLOW = 10e9;
- // cin >> N;
- // vector <int> GRAPHFlags(N);
- // for (int i = 0; i < N; cin >> GRAPHFlags[i], i++) {}
- // GRAPH = vector <vector <int>>(N + 2, vector <int>(N + 2));
- // for (int i = 0; i < N; i++) {
- // for (int j = 0; j < N; cin >> GRAPH[i][j], j++) {}
- // }
- // START = N, END = N + 1;
- //
- // for (int i = 0; i < N; i++) {
- // if (GRAPHFlags[i] == 1) {
- // GRAPH[START][i] = MAXFLOW;
- // }
- // }
- //
- // for (int i = 0; i < N; i++) {
- // if (GRAPHFlags[i] == 2) {
- // GRAPH[i][END] = MAXFLOW;
- // }
- // }
- //
- // N += 2;
- // FLOWS = vector <vector <int>>(N, vector <int>(N, 0));
- //
- // while (true) {
- // int temp = bfs(START);
- // if (temp < 0) {
- // break;
- // }
- // }
- //
- // int res = 0;
- // for (int i = 0; i < N; i++) {
- // res += FLOWS[i][END];
- // }
- // cout << res << endl;
- // return 0;
- //}
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <vector>
- #include <queue>
- #include <set>
- #include <stack>
- #include <algorithm>
- using namespace std;
- struct Edge;
- int N, M, K;
- int INFIMUM = 10e6;
- vector <vector <int>> ROADS;
- vector <int> PHI;
- int START, FINISH = 0;
- vector <vector <Edge>> EDGES;
- vector <vector <Edge*>> BACKEDGES;
- vector <Edge*> WAY;
- set <int> VISITED;
- struct Edge {
- int from;
- int target;
- int cost;
- int flow;
- int indent;
- int maxCapacity;
- Edge(int from = -1, int target = -1, int cost = -1, int flow = -1, int maxCapacity = -1, int indent = -1) :
- from(from), target(target), cost(cost), flow(flow), maxCapacity(maxCapacity), indent(indent) {};
- int getCapacity() {
- return maxCapacity - flow;
- }
- int getCost() const {
- return cost + PHI[target] - PHI[from];
- }
- };
- struct DijkstraStruct {
- int val;
- int index;
- Edge* edge;
- DijkstraStruct(int val = 0, int index = 0, Edge* edge = nullptr) : val(val), index(index), edge(edge) {};
- };
- const bool operator < (const Edge& left, const Edge& right) {
- return left.getCost() < right.getCost();
- }
- const bool operator < (const DijkstraStruct& left, const DijkstraStruct& right) {
- return left.val > right.val;
- }
- Edge* getEdgeBack(Edge* e) {
- // for (auto edge : EDGES[e->target]) {
- // if (edge.indent == -e->indent && edge.from == e->target) {
- // return &edge;
- // }
- // }
- for (int i = 0; i < EDGES[e->target].size(); i++) {
- if (EDGES[e->target][i].indent == -e->indent && EDGES[e->target][i].from == e->target) {
- return &EDGES[e->target][i];
- }
- }
- }
- int dijkstra() {
- set <int> visitied;
- vector <DijkstraStruct> verts(N);
- /*for (auto temp : verts) {
- temp.val = INFIMUM;
- }*/
- for (int i = 0; i < verts.size(); i++) {
- verts[i].val = INFIMUM;
- verts[i].index = i;
- }
- verts[FINISH].val = 0;
- priority_queue<DijkstraStruct> queue;
- queue.push(verts[FINISH]);
- while (!queue.empty()) {
- DijkstraStruct temp = queue.top();
- queue.pop();
- if (visitied.find(temp.index) != visitied.end()) {
- continue;
- }
- visitied.insert(temp.index);
- /*for (auto edge : BACKEDGES[temp.index]) {
- if (edge.getCapacity() > 0) {
- if (verts[edge.from].val > verts[edge.target].val + edge.getCost()) {
- verts[edge.from] = DijkstraStruct(verts[edge.target].val + edge.getCost(), edge.from, &edge);
- queue.push(verts[edge.from]);
- }
- }
- }*/
- for (int i = 0; i < BACKEDGES[temp.index].size(); i++) {
- auto edge = BACKEDGES[temp.index][i];
- if (edge->getCapacity() > 0) {
- if (verts[edge->from].val > verts[edge->target].val + edge->getCost()) {
- verts[edge->from] = DijkstraStruct(verts[edge->target].val + edge->getCost(), edge->from, BACKEDGES[temp.index][i]);
- queue.push(verts[edge->from]);
- }
- }
- }
- }
- if (verts[START].val == INFIMUM) {
- return 0;
- }
- for (int i = 0; i < N; i++) {
- PHI[i] += verts[i].val;
- }
- int cur = START;
- vector <int> way;
- while (cur != FINISH) {
- DijkstraStruct temp = verts[cur];
- temp.edge->flow += 1;
- Edge* backedge = nullptr;
- backedge = getEdgeBack(temp.edge);
- if (backedge != nullptr) {
- backedge->flow -= 1;
- }
- cur = temp.edge->target;
- }
- return 1;
- }
- bool getWay(int v = START) {
- if (v == START) {
- WAY.clear();
- VISITED.clear();
- }
- if (v == FINISH) {
- return true;
- }
- if (VISITED.find(v) != VISITED.end()) {
- return false;
- }
- VISITED.insert(v);
- for (int i = 0; i < EDGES[v].size(); i++) {
- if (EDGES[v][i].flow > 0) {
- if (getWay(EDGES[v][i].target)) {
- WAY.push_back(&EDGES[v][i]);
- return true;
- }
- }
- }
- }
- int main() {
- freopen("brides.in", "r", stdin);
- freopen("brides.out", "w", stdout);
- cin >> N >> M >> K;
- ROADS = vector <vector <int>>(M, vector<int>(3));
- for (int i = 0; i < M; i++) {
- for (int j = 0; j < 3; j++) {
- cin >> ROADS[i][j];
- }
- ROADS[i].push_back(i + 1);
- }
- N += 1;
- START = 0;
- FINISH = N - 1;
- PHI = vector <int>(N);
- PHI[FINISH] = 0;
- EDGES = vector <vector <Edge>>(N);
- BACKEDGES = vector <vector <Edge*>>(N);
- EDGES[0].push_back(Edge(0, 1, 0, 0, K, 0));
- EDGES[1].push_back(Edge(1, 0, 0, 0, 0, 0));
- BACKEDGES[0].push_back(new Edge(0, 1, 0, 0, 0, 0));
- BACKEDGES[1].push_back(new Edge(1, 0, 0, 0, K, 0));
- for (auto r : ROADS) {
- EDGES[r[0]].push_back(Edge(r[0], r[1], r[2], 0, 1, r[3]));
- EDGES[r[1]].push_back(Edge(r[1], r[0], r[2], 0, 1, r[3]));
- EDGES[r[0]].push_back(Edge(r[0], r[1], -r[2], 0, 0, -r[3]));
- EDGES[r[1]].push_back(Edge(r[1], r[0], -r[2], 0, 0, -r[3]));
- }
- /*for (auto line : EDGES) {
- for (auto edge : line) {
- BACKEDGES[edge.target].push_back(&edge);
- }
- }*/
- for (int i = 0; i < EDGES.size(); i++) {
- for (int j = 0; j < EDGES[i].size(); j++) {
- BACKEDGES[EDGES[i][j].target].push_back(&EDGES[i][j]);
- }
- }
- int temp = 1;
- while (temp > 0) {
- temp = dijkstra();
- }
- int flowVal = 0;
- for (size_t i = 0; i < EDGES[START].size(); i++) {
- if (EDGES[START][i].flow > 0) {
- flowVal += EDGES[START][i].flow;
- }
- }
- if (flowVal < K) {
- cout << "-1" << endl;
- return 0;
- }
- double average = 0.0;
- double tempSum = 0;
- for (auto i : EDGES) {
- for (auto elem : i) {
- if (elem.flow > 0) {
- tempSum += elem.cost;
- }
- }
- }
- average = tempSum / K;
- vector <vector <Edge*>> pathWays;
- for (int i = 0; i < K; i++) {
- getWay();
- vector <Edge*> tmpWay = WAY;
- reverse(tmpWay.begin(), tmpWay.end());
- pathWays.push_back(tmpWay);
- for (int j = 0; j < WAY.size(); j++) {
- WAY[j]->flow -= 1;
- }
- }
- printf("%0.6f\n", average);
- for (auto i : pathWays) {
- cout << i.size() - 1 << " ";
- for (int j = 1; j < i.size(); j++) {
- cout << i[j]->indent << " ";
- }
- cout << endl;
- }
- //priority_queue<int> test;
- //test.push(-5);
- //test.push(-1);
- //test.push(-1);
- //while (!test.empty()) {
- // cout << test.top() << endl;
- // test.pop();
- //}
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement