Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <list>
  5.  
  6. namespace NFlow {
  7.  
  8. typedef long long TFlow;
  9. typedef unsigned int TVertex;
  10.  
  11. struct Edge {
  12. TVertex from, to;
  13. TFlow capacity, flow;
  14. };
  15.  
  16. struct BadVertexId : public std::exception {};
  17. struct BadEdge : public std::exception {};
  18. struct SourceEqualsSink : public std::exception {};
  19.  
  20. class Network {
  21. protected:
  22.  
  23. std::vector<Edge> edges_;
  24. std::vector<int> lasts_, prev_;
  25. std::vector<int> inv_lasts_, inv_prev_;
  26.  
  27. unsigned int vertexNumber_;
  28. TVertex source_, sink_;
  29.  
  30. void addEdgeLocal_(TVertex from, TVertex to, TFlow capacity) {
  31. if (from < 0 || from >= vertexNumber_) {
  32. throw BadVertexId();
  33. }
  34. if (to < 0 || to >= vertexNumber_) {
  35. throw BadVertexId();
  36. }
  37. edges_.push_back({from, to, capacity, 0});
  38.  
  39. prev_.push_back(lasts_[from]);
  40. lasts_[from] = (int) edges_.size() - 1;
  41.  
  42. inv_prev_.push_back(inv_lasts_[to]);
  43. inv_lasts_[to] = (int) edges_.size() - 1;
  44. }
  45.  
  46. void pushFlow_(int edge, TFlow flow) {
  47. edges_[edge].flow += flow;
  48. edges_[edge ^ 1].flow -= flow;
  49. }
  50.  
  51. public:
  52. Network(int n, TVertex source, TVertex sink)
  53. : vertexNumber_(n),
  54. source_(source),
  55. sink_(sink),
  56. lasts_(n, -1),
  57. inv_lasts_(n, -1) {
  58. if (source_ >= vertexNumber_ || sink_ >= vertexNumber_) {
  59. throw BadVertexId();
  60. }
  61. if (source_ == sink_) {
  62. throw SourceEqualsSink();
  63. }
  64. }
  65.  
  66. void addEdge(TVertex from, TVertex to, int capacity) {
  67. addEdgeLocal_(from, to, capacity);
  68. addEdgeLocal_(to, from, 0);
  69. }
  70.  
  71. unsigned int getVertexNumber() const {
  72. return vertexNumber_;
  73. }
  74.  
  75. TVertex getSource() const {
  76. return source_;
  77. }
  78.  
  79. TVertex getSink() const {
  80. return sink_;
  81. }
  82.  
  83. friend class EdgeIterator;
  84.  
  85. class EdgeIterator {
  86. protected:
  87. friend class Network;
  88.  
  89. int edgeId_;
  90. Network &network_;
  91. bool isForward_;
  92.  
  93. EdgeIterator(int id, Network &network, bool isForward = true)
  94. : edgeId_(id),
  95. network_(network),
  96. isForward_(isForward) {}
  97.  
  98. public:
  99. EdgeIterator &operator=(const EdgeIterator &a) {
  100. edgeId_ = a.edgeId_;
  101. network_ = a.network_;
  102. isForward_ = a.isForward_;
  103. return *this;
  104. }
  105.  
  106. bool isValid() const {
  107. return edgeId_ >= 0;
  108. }
  109.  
  110. EdgeIterator &goNext() {
  111. if (!isValid()) {
  112. throw BadEdge();
  113. }
  114. if (isForward_) {
  115. edgeId_ = network_.prev_[edgeId_];
  116. } else {
  117. edgeId_ = network_.inv_prev_[edgeId_];
  118. }
  119. return *this;
  120. }
  121.  
  122. TVertex getFrom() const {
  123. return network_.edges_[edgeId_].from;
  124. }
  125.  
  126. TVertex getTo() const {
  127. return network_.edges_[edgeId_].to;
  128. }
  129.  
  130. TFlow getCapacity() const {
  131. return network_.edges_[edgeId_].capacity;
  132. }
  133.  
  134. TFlow getFlow() const {
  135. return network_.edges_[edgeId_].flow;
  136. }
  137.  
  138. TFlow getResudialCapacity() const {
  139. return getCapacity() - getFlow();
  140. }
  141.  
  142. void pushFlow(TFlow flow) const {
  143. network_.pushFlow_(edgeId_, flow);
  144. }
  145. };
  146.  
  147. EdgeIterator getListBegin(TVertex vertex, bool isForward = true) {
  148. return EdgeIterator((isForward ? lasts_[vertex] : inv_lasts_[vertex]), *this, isForward);
  149. }
  150.  
  151. TFlow getFullFlow() {
  152. TFlow res = 0;
  153. for (auto it = getListBegin(getSource()); it.isValid(); it.goNext()) {
  154. res += it.getFlow();
  155. }
  156. return res;
  157. }
  158. };
  159.  
  160. class Mincut {
  161. protected:
  162. Network *network_;
  163. std::vector<bool> inLeftPart_;
  164.  
  165. void residualDfs_(TVertex vertex) {
  166. if (inLeftPart_[vertex]) return;
  167. inLeftPart_[vertex] = true;
  168. for (auto it = network_->getListBegin(vertex); it.isValid(); it.goNext()) {
  169. if (it.getResudialCapacity() > 0) {
  170. residualDfs_(it.getTo());
  171. }
  172. }
  173. }
  174.  
  175. void build_() {
  176. inLeftPart_.assign(network_->getVertexNumber(), false);
  177. residualDfs_(network_->getSource());
  178. }
  179.  
  180. public:
  181. explicit Mincut(Network *network) : network_(network) {
  182. unsigned int n = network_->getVertexNumber();
  183. inLeftPart_.assign(n, false);
  184. build_();
  185. }
  186. bool inLeft(TVertex vertex) {
  187. return inLeftPart_[vertex];
  188. }
  189. };
  190.  
  191. class IFlow {
  192. protected:
  193. Network *network_;
  194. public:
  195. explicit IFlow(Network *network) : network_(network) {}
  196. explicit IFlow() : network_(nullptr) {}
  197.  
  198. Network *getNetwork() {
  199. return network_;
  200. }
  201.  
  202. void setNetwork(Network *network) {
  203. network_ = network;
  204. }
  205.  
  206. virtual void run() = 0;
  207. virtual ~IFlow() = default;
  208. };
  209.  
  210. class BlockingFlow : public IFlow {
  211. private:
  212. void createLayer_() {
  213. layer_.assign(network_->getVertexNumber(), -1);
  214. layer_[network_->getSource()] = 0;
  215. std::queue<TVertex> q;
  216. q.push(network_->getSource());
  217. while (!q.empty()) {
  218. TVertex v = q.front();
  219. q.pop();
  220. for (Network::EdgeIterator it = network_->getListBegin(v); it.isValid(); it.goNext()) {
  221. if (layer_[it.getTo()] == -1 && it.getResudialCapacity() > 0) {
  222. layer_[it.getTo()] = layer_[v] + 1;
  223. q.push(it.getTo());
  224. }
  225. }
  226. }
  227. }
  228. bool sinkIsReachable_() {
  229. return layer_[network_->getSink()] != -1;
  230. }
  231. protected:
  232. std::vector <int> layer_;
  233. virtual void findBlockingFlow() = 0;
  234.  
  235. public:
  236. explicit BlockingFlow(Network *network) : IFlow(network), layer_(network_->getVertexNumber(), -1) {}
  237. explicit BlockingFlow() : IFlow(), layer_(0) {}
  238.  
  239. void run() override {
  240. createLayer_();
  241. while (sinkIsReachable_()) {
  242. findBlockingFlow();
  243. createLayer_();
  244. }
  245. }
  246. };
  247.  
  248. class MKM : public BlockingFlow {
  249. protected:
  250. static const TFlow INF_Flow = 1e18 + 7;
  251.  
  252. std::vector<TFlow> sumIn_, sumOut_;
  253. std::vector<bool> erased_;
  254.  
  255. TFlow getPotential_(TVertex vertex) {
  256. return std::min(sumIn_[vertex], sumOut_[vertex]);
  257. }
  258.  
  259. void createPotential_() {
  260. unsigned int n = network_->getVertexNumber();
  261. sumIn_.assign(n, 0);
  262. sumOut_.assign(n, 0);
  263. for (TVertex v = 0; v < n; v++) {
  264. for (int isForward = 0; isForward < 2; isForward++) {
  265. for (Network::EdgeIterator it = network_->getListBegin(v, isForward); it.isValid(); it.goNext()) {
  266. if (layer_[(it.getFrom())] + 1 != layer_[(it.getTo())]) continue;
  267. if (isForward) {
  268. sumOut_[v] += it.getResudialCapacity();
  269. } else {
  270. sumIn_[v] += it.getResudialCapacity();
  271. }
  272. }
  273. }
  274. if (v == network_->getSource()) {
  275. sumIn_[v] = INF_Flow;
  276. }
  277. if (v == network_->getSink()) {
  278. sumOut_[v] = INF_Flow;
  279. }
  280. }
  281. }
  282.  
  283. void updatePotential_(Network::EdgeIterator it) {
  284. if (layer_[it.getFrom()] + 1 == layer_[it.getTo()]) {
  285. sumOut_[it.getFrom()] -= it.getResudialCapacity();
  286. sumIn_[it.getTo()] -= it.getResudialCapacity();
  287. }
  288. }
  289.  
  290. void tryToErase_() {
  291. bool found = true;
  292. while (found) {
  293. found = false;
  294. for (TVertex vertex = 0; vertex < network_->getVertexNumber(); vertex++) {
  295. if (erased_[vertex] || getPotential_(vertex) > 0) continue;
  296. erased_[vertex] = true;
  297. for (int isForward = 0; isForward < 2; isForward++) {
  298. for (auto it = network_->getListBegin(vertex, isForward); it.isValid(); it.goNext()) {
  299. updatePotential_(it);
  300. }
  301. }
  302. found = true;
  303. break;
  304. }
  305. }
  306. }
  307.  
  308. void pushToward_(TVertex vertex, TFlow min_potential, bool isForward) {
  309. std::queue<std::pair<TVertex, TFlow> > q;
  310. q.push({vertex, min_potential});
  311. while (!q.empty()) {
  312. TVertex now = q.front().first;
  313. TFlow need = q.front().second;
  314. q.pop();
  315. for (auto it = network_->getListBegin(now, isForward); (need > 0 && it.isValid());
  316. updatePotential_(it), it.goNext()) {
  317. int layer_from = layer_[it.getFrom()];
  318. int layer_to = layer_[it.getTo()];
  319. if (layer_from + 1 != layer_to) continue;
  320. TVertex nxt = (isForward ? it.getTo() : it.getFrom());
  321. if (erased_[nxt]) continue;
  322. TFlow flow = std::min(need, it.getResudialCapacity());
  323. if (!flow) continue;
  324. q.push({nxt, flow});
  325. it.pushFlow(flow);
  326. sumOut_[it.getFrom()] -= flow;
  327. sumIn_[it.getTo()] -= flow;
  328. need -= flow;
  329. if (!need) break;
  330. }
  331. }
  332. }
  333.  
  334. void findBlockingFlow() override {
  335. createPotential_();
  336. erased_.assign(network_->getVertexNumber(), false);
  337. while (true) {
  338. tryToErase_();
  339. if (erased_[network_->getSource()] || erased_[network_->getSink()]) break;
  340. TFlow min_potential = INF_Flow;
  341. TVertex vertex = network_->getSource();
  342. for (TVertex v = 0; v < network_->getVertexNumber(); v++) {
  343. TFlow now_potential = getPotential_(v);
  344. if (!erased_[v] && now_potential < min_potential) {
  345. min_potential = now_potential;
  346. vertex = v;
  347. }
  348. }
  349. pushToward_(vertex, min_potential, true);
  350. pushToward_(vertex, min_potential, false);
  351. }
  352. }
  353.  
  354. public:
  355. explicit MKM(Network *network) : BlockingFlow(network) {
  356. unsigned int n = network_->getVertexNumber();
  357. sumIn_.resize(n, 0);
  358. sumOut_.resize(n, 0);
  359. erased_.resize(n, false);
  360. }
  361. explicit MKM() : BlockingFlow(), sumIn_(0), sumOut_(0), erased_(0) {}
  362. };
  363.  
  364. class PushRelabel : public IFlow {
  365. protected:
  366. static const int INF = 1e9 + 7;
  367. std::vector<int> height_;
  368. std::vector<TFlow> excess_;
  369. void initialize_() {
  370. unsigned int n = network_->getVertexNumber();
  371. height_.assign(n, 0);
  372. excess_.assign(n, 0);
  373. TVertex source = network_->getSource();
  374. height_[source] = n;
  375. for (auto it = network_->getListBegin(source); it.isValid(); it.goNext()) {
  376. excess_[it.getTo()] += it.getResudialCapacity();
  377. it.pushFlow(it.getResudialCapacity());
  378. }
  379. }
  380.  
  381. void push_(Network::EdgeIterator &it) {
  382. if (height_[it.getFrom()] != height_[it.getTo()] + 1) return;
  383. TFlow flow = std::min(excess_[it.getFrom()], it.getResudialCapacity());
  384. it.pushFlow(flow);
  385. excess_[it.getFrom()] -= flow;
  386. excess_[it.getTo()] += flow;
  387. }
  388.  
  389. void relabel_(TVertex vertex) {
  390. int minh = INF;
  391. for (auto it = network_->getListBegin(vertex); it.isValid(); it.goNext()) {
  392. if (it.getResudialCapacity() == 0) continue;
  393. minh = std::min(minh, height_[it.getTo()]);
  394. }
  395. if (minh != INF) {
  396. height_[vertex] = minh + 1;
  397. }
  398. }
  399.  
  400. virtual void pushExcess() = 0;
  401.  
  402. public:
  403. explicit PushRelabel(Network *network) : IFlow(network) {
  404. unsigned int n = network->getVertexNumber();
  405. height_.resize(n), excess_.resize(n);
  406. }
  407. explicit PushRelabel() : IFlow(), height_(0), excess_(0) {}
  408.  
  409. void run() override {
  410. initialize_();
  411. pushExcess();
  412. }
  413. };
  414.  
  415. class PushRelabelToFront : public PushRelabel {
  416. protected:
  417. std::vector<Network::EdgeIterator> iterators_;
  418. std::list<TVertex> order_;
  419.  
  420. void discharge_(TVertex vertex) {
  421. while (excess_[vertex]) {
  422. if (!iterators_[vertex].isValid()) {
  423. relabel_(vertex);
  424. iterators_[vertex] = network_->getListBegin(vertex);
  425. } else {
  426. int from = iterators_[vertex].getFrom(), to = iterators_[vertex].getTo();
  427. if (iterators_[vertex].getResudialCapacity() > 0 && height_[from] == height_[to] + 1) {
  428. push_(iterators_[vertex]);
  429. } else {
  430. iterators_[vertex].goNext();
  431. }
  432. }
  433. }
  434. }
  435.  
  436. void pushExcess() override {
  437. for (TVertex vertex = 0; vertex < network_->getVertexNumber(); vertex++) {
  438. if (vertex != network_->getSource() && vertex != network_->getSink()) {
  439. order_.push_back(vertex);
  440. }
  441. iterators_.push_back(network_->getListBegin(vertex));
  442. }
  443. auto it = order_.begin();
  444. while (it != order_.end()) {
  445. TVertex vertex = *it;
  446. int old_h = height_[vertex];
  447. discharge_(vertex);
  448. if (height_[vertex] != old_h) {
  449. order_.erase(it);
  450. order_.push_front(vertex);
  451. it = order_.begin();
  452. }
  453. it++;
  454. }
  455. }
  456.  
  457. public:
  458. explicit PushRelabelToFront(Network *network) : PushRelabel(network) {}
  459. explicit PushRelabelToFront() : PushRelabel() {}
  460. };
  461. }
  462.  
  463. struct Data {
  464. int n;
  465. std::vector <int> a;
  466. std::vector <std::vector <int> > dependences;
  467. };
  468.  
  469. Data readInput(std::istream &in) {
  470. int n;
  471. std::vector <int> a;
  472. std::vector <std::vector <int> > dependences;
  473. in >> n;
  474. a.resize(n);
  475. for (int i = 0; i < n; i++) {
  476. in >> a[i];
  477. }
  478. dependences.resize(n);
  479. for (int i = 0; i < n; i++) {
  480. int cnt;
  481. in >> cnt;
  482. for (int j = 0; j < cnt; j++) {
  483. int dep;
  484. in >> dep;
  485. dep--;
  486. dependences[i].push_back(dep);
  487. }
  488. }
  489. return {n, a, dependences};
  490. }
  491.  
  492. NFlow::Network createNetwork(const Data &data) {
  493. const int INF = 1e9 + 7;
  494. int N = data.n + 2, source = N - 2, sink = N - 1;
  495. NFlow::Network network(N, source, sink);
  496.  
  497. for (int i = 0; i < data.n; i++) {
  498. if (data.a[i] > 0) {
  499. network.addEdge(i, network.getSink(), data.a[i]);
  500. } else {
  501. network.addEdge(network.getSource(), i, -data.a[i]);
  502. }
  503. for (int v : data.dependences[i]) {
  504. network.addEdge(v, i, INF);
  505. }
  506. }
  507. return network;
  508. }
  509.  
  510. long long solveWithFlows(NFlow::IFlow *flow, const Data &data) {
  511. auto network = createNetwork(data);
  512. flow->setNetwork(&network);
  513. flow->run();
  514. NFlow::Mincut mincut(flow->getNetwork());
  515. long long result = 0;
  516. for (int i = 0; i < data.n; i++) {
  517. if (!mincut.inLeft(i)) {
  518. result += data.a[i];
  519. }
  520. }
  521. return result;
  522. }
  523.  
  524. void solve() {
  525. int n;
  526. std::vector <int> a;
  527. std::vector <std::vector <int> > dependences;
  528. long long result;
  529. Data data = readInput(std::cin);
  530. result = solveWithFlows(new NFlow::PushRelabelToFront(), data);
  531. std:: cout << result << "\n";
  532. }
  533.  
  534.  
  535. int main() {
  536. solve();
  537. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement