zoukankan      html  css  js  c++  java
  • poj 3436 最大流+拆点

    今天总算明白了最大流中的拆点的含义,

    因为最大流的中两个点u和v,流量的限制记为cap(u,v),

    如果一个点u的流量限制为m,那么我们可以把u拆成u1和u2

    并且对任意的s,将cap(s,u)换成cap(s,u1),

    对任意的e,将cap(u,e)换成cap(u1,e),

    最后将cap(u1,u2)置为m,然后套用最大流的通用算法即可

      1 #include <iostream>
      2 #include <string>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <map>
      7 #include <algorithm>
      8 #include <list>
      9 #include <ctime>
     10 #include <set>
     11 #include <string.h>
     12 #include <queue>
     13 using namespace std;
     14 
     15 #define N 1050
     16 int capacity[N][N]; //容量
     17 int capacity2[N][N]; //容量
     18 int flow[N]; //残余流量
     19 int pre[N]; //前趋
     20 #define INT_MAX 10000000;
     21 
     22 int n, m;
     23 queue<int> Q;
     24 
     25 int BFS(int src, int des) {
     26     //初始化
     27     while (!Q.empty()) {
     28         Q.pop();
     29     }
     30     for (int i = 1; i < n + 1; i++) {
     31         pre[i] = -1;
     32     }
     33     pre[src] = 0;
     34     flow[src] = INT_MAX; //初始化源点的流量为无穷大
     35     Q.push(src);
     36     while (!Q.empty()) {
     37         int index = Q.front();
     38         Q.pop();
     39         if (index == des) { //找到了增广路径
     40             break;
     41         }
     42         for (int i = 1; i < n + 1; i++) {
     43             if (i != src && capacity[index][i] > 0 && pre[i] == -1) {
     44                 pre[i] = index;
     45                 //增广路残容流量
     46                 flow[i] = min(capacity[index][i], flow[index]);
     47                 Q.push(i);
     48             }
     49         }
     50     } //while
     51     if (pre[des] == -1) {
     52         return -1; //残留图中不存在增广路径
     53     } else {
     54         return flow[des];
     55     }
     56 }
     57 
     58 int MaxFlow(int src, int des) {
     59     int aug = 0;
     60     int sumflow = 0;
     61     while ((aug = BFS(src, des)) != -1) {
     62         int k = des; //利用前驱寻找路径
     63         while (k != src) {
     64             int last = pre[k];
     65             capacity[last][k] -= aug;
     66             capacity[k][last] += aug;
     67             k = last;
     68         }
     69         sumflow += aug;
     70     }
     71     return sumflow;
     72 }
     73 struct node {
     74     string in, out;
     75     int cap;
     76 };
     77 int checkin(string & a, string& b) {
     78     int sz = a.size();
     79     bool judge = 1;
     80     for (int i = 0; i < sz; i++) {
     81         if (a[i] == '2' || b[i] == '2') {
     82             continue;
     83         } else if (a[i] != b[i]) {
     84             judge = 0;
     85             break;
     86         }
     87     }
     88     if (1 == judge)
     89         return 1;
     90     return 0;
     91 }
     92 int main() {
     93     int kp, kn, cap;
     94     cin >> kp >> kn;
     95     n = 2 * kn + 2;
     96     vector<node> data;
     97     string startstate;
     98     string endstate;
     99     string csta = "0";
    100     string cend = "1";
    101     for (int i = 0; i < kp; i++) {
    102         startstate += csta;
    103         endstate += cend;
    104     }
    105     for (int i = 0; i < kn; i++) {
    106         cin >> cap;
    107         string t, t2;
    108         string statein, stateout;
    109         for (int j = 0; j < kp; j++) {
    110             cin >> t;
    111             statein = statein + t;
    112         }
    113         t = t2;
    114         for (int j = 0; j < kp; j++) {
    115             cin >> t;
    116             stateout = stateout + t;
    117         }
    118         node tmp;
    119         tmp.cap = cap;
    120         tmp.in = statein;
    121         tmp.out = stateout;
    122         data.push_back(tmp);
    123     }
    124     for (int i = 0; i < kn; i++) {
    125         node tmp = data[i];
    126         int u = i + 1;
    127         int v = i + 1 + kn;
    128         capacity[u][v] = tmp.cap;
    129         int judge = checkin(startstate, tmp.in);
    130         if (1 == judge) {
    131             capacity[0][u] = tmp.cap;
    132         }
    133         judge = checkin(tmp.out, endstate);
    134         if (1 == judge) {
    135             capacity[v][n - 1] = tmp.cap;
    136         }
    137 
    138         for (int j = 0; j < kn; j++) {
    139             if (j != i) {
    140                 node tmp2 = data[j];
    141                 int u2 = j + 1;
    142                 int v2 = j + 1 + kn;
    143                 judge = checkin(tmp2.out, tmp.in);
    144                 if (1 == judge) {
    145                     capacity[v2][u] = tmp2.cap;
    146                 }
    147                 judge = checkin(tmp.out, tmp2.in);
    148                 if (1 == judge) {
    149                     capacity[v][u2] = tmp.cap;
    150                 }
    151             }
    152 
    153         }
    154     }
    155     for (int i = 0; i < N; i++) {
    156         for (int j = 0; j < N; j++) {
    157             capacity2[i][j] = capacity[i][j];
    158         }
    159     }
    160     int sum = MaxFlow(0, n - 1);
    161     cout << sum <<" ";
    162     int num=0;
    163     for (int i = 0; i < kn; i++) {
    164         node tmp = data[i];
    165         int u = i + 1;
    166         int v = i + 1 + kn;
    167         int judge;
    168 
    169         for (int j = 0; j < kn; j++) {
    170             if (j != i) {
    171                 node tmp2 = data[j];
    172                 int u2 = j + 1;
    173                 int v2 = j + 1 + kn;
    174                 judge = checkin(tmp.out, tmp2.in);
    175                 if (1 == judge) {
    176                     int cost = capacity2[v][u2] - capacity[v][u2];
    177                     if (cost > 0) {
    178                         num++;
    179                     }
    180                 }
    181             }
    182         }
    183     }
    184     cout<<num<<endl;
    185 
    186     for (int i = 0; i < kn; i++) {
    187         node tmp = data[i];
    188         int u = i + 1;
    189         int v = i + 1 + kn;
    190         int judge;
    191 
    192         for (int j = 0; j < kn; j++) {
    193             if (j != i) {
    194                 node tmp2 = data[j];
    195                 int u2 = j + 1;
    196                 int v2 = j + 1 + kn;
    197                 judge = checkin(tmp.out, tmp2.in);
    198                 if (1 == judge) {
    199                     int cost = capacity2[v][u2] - capacity[v][u2];
    200                     if (cost > 0) {
    201                         cout << i + 1 << " " << j + 1 << " " << cost << endl;
    202                     }
    203                 }
    204             }
    205 
    206         }
    207     }
    208     return 0;
    209 }
  • 相关阅读:
    LocalDateTime和Date使用@JsonFormat显示毫秒时间
    curl查看ip的几种方式
    thinkphp5.1生成缩略图很模糊
    ajax发送时禁用按钮
    thinkphp5 不使用form,用input+ajax异步上传图片
    GOLANG 闭包和普通函数的区别
    GOLANG 匿名函数笔记
    父级自适应自己高度且高度完全一致css
    子元素等高 css
    ios 用jquery为元素标签绑定点击事件时,ios上不执行点击事件
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3055948.html
Copyright © 2011-2022 走看看