• POJ 3436:ACM Computer Factory(最大流记录路径)


    http://poj.org/problem?id=3436

    题意:题意很难懂。给出P N。接下来N行代表N个机器,每一行有2*P+1个数字

    第一个数代表容量,第2~P+1个数代表输入,第P+2到2*P+1是代表输出

    输入有三种情况,0,1,2.输出有0,1两种情况
    输入0代表不能有这个接口,1代表必须要有这个接口,2代表这个接口可有可无。
    输出0代表有这个接口,1代表没有这个接口。大概输出就是像插头,输入像插座,只有接口吻合才可以相连。

    思路:比较简单的最大流,主要是理解题意很难,把每台机器拆成输入和输出两个点,之间的流量就是第一个数那个流量,然后把符合题意的输入和超级源点相连,把符合题意的输出和超级汇点相连,把符合题意的机器之间的输入输出相连,流量都是INF,用ISAP找到增广路更新的时候,可以顺便记录路径。也可以最后和初始流量比较,如果减少了就说明有流量经过。可是ISAP模板错了导致一直WA了好久,以为是思路错了,用Dinic做过了,这里重新找了份鸟神的模板Orz。

    Dinic:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <queue>
      5 #include <vector>
      6 using namespace std;
      7 #define N 400
      8 const int INF = 0x3f3f3f3f;
      9 
     10 struct Edge {
     11     int u, v, cap, init;
     12     Edge () {}
     13     Edge (int u, int v, int cap, int init) : u(u), v(v), cap(cap), init(init) {}
     14 }edge[N];
     15 vector<int> G[N];
     16 int cur[N], dis[N], gap[N], pre[N], tot, S, T;
     17 int mp[N][N], info[N][N];
     18 
     19 void Add(int u, int v, int cap) {
     20     edge[tot] = Edge(u, v, cap, cap);
     21     G[u].push_back(tot++);
     22     edge[tot] = Edge(v, u, 0, 0);
     23     G[v].push_back(tot++);
     24 }
     25 
     26 int BFS() {
     27     queue<int> que;
     28     while(!que.empty()) que.pop();
     29     memset(dis, INF, sizeof(dis));
     30     dis[S] = 0; que.push(S);
     31     while(!que.empty()) {
     32         int u = que.front(); que.pop();
     33         for(int i = 0; i < G[u].size(); i++) {
     34             Edge& e = edge[G[u][i]];
     35             if(dis[e.v] == INF && e.cap > 0) {
     36                 dis[e.v] = dis[u] + 1;
     37                 que.push(e.v);
     38             }
     39         }
     40     }
     41     return dis[T] < INF;
     42 }
     43 
     44 int DFS(int u, int maxflow) {
     45     if(u == T) return maxflow;
     46     for(int i = cur[u]; i < G[u].size(); i++) {
     47         cur[u] = i; Edge& e = edge[G[u][i]];
     48         if(dis[e.v] == dis[u] + 1 && e.cap > 0) {
     49             int flow = DFS(e.v, min(maxflow, e.cap));
     50             if(flow > 0) {
     51                 e.cap -= flow;
     52                 edge[G[u][i] ^ 1].cap += flow;
     53                 return flow;
     54             }
     55         }
     56     }
     57     return 0;
     58 }
     59 
     60 int Dinic() {
     61     int ans = 0;
     62     while(BFS()) {
     63         memset(cur, 0, sizeof(cur));
     64         int flow;
     65         while(flow = DFS(S, INF)) ans += flow;
     66     }
     67     return ans;
     68 }
     69 
     70 int main() {
     71     int P, n;
     72     while(~scanf("%d%d", &P, &n)) {
     73         tot = 0; S = 0, T = 2 * n + 1;
     74         for(int i = S; i <= T; i++) G[i].clear();
     75         memset(mp, 0, sizeof(mp));
     76         for(int i = 1; i <= n; i++) {
     77             scanf("%d", &info[i][0]);
     78             for(int j = 1; j <= P; j++)
     79                 scanf("%d", &info[i][j]);
     80             for(int j = 1; j <= P; j++)
     81                 scanf("%d", &info[i][j+P]);
     82         }
     83         for(int i = 1; i <= n; i++) {
     84             Add(i, i + n, info[i][0]);
     85             int fs = 1, ft = 1;
     86             for(int j = 1; j <= P; j++) {
     87                 if(info[i][j] == 1) fs = 0;
     88                 if(info[i][j+P] == 0) ft = 0;
     89             }
     90             if(fs) Add(S, i, INF);
     91             if(ft) Add(i + n, T, INF);
     92             for(int j = 1; j <= n; j++) {
     93                 if(i == j) continue;
     94                 fs = 1;
     95                 for(int k = 1; k <= P; k++)
     96                     if(info[i][k+P] != info[j][k] && info[j][k] != 2)
     97                         fs = 0;
     98                 if(fs) Add(i + n, j, INF);
     99             }
    100         }
    101         int ans = Dinic(), cnt = 0;
    102         for(int u = n + 1; u <= 2 * n; u++) {
    103             for(int j = 0; j < G[u].size(); j++) {
    104                 Edge& e = edge[G[u][j]];
    105                 if(e.v <= n && e.v > 0 && e.cap < e.init) mp[u-n][e.v] += e.init - e.cap;
    106             }
    107         }
    108         for(int i = 1; i <= n; i++) {
    109             for(int j = 1; j <= n; j++) {
    110                 if(mp[i][j]) cnt++;
    111             }
    112         }
    113         printf("%d %d
    ", ans, cnt);
    114         for(int i = 1; i <= n; i++) {
    115             for(int j = 1; j <= n; j++) {
    116                 if(mp[i][j]) printf("%d %d %d
    ", i, j, mp[i][j]);
    117             }
    118         }
    119     }
    120     return 0;
    121 }

    ISAP:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <queue>
      5 #include <vector>
      6 using namespace std;
      7 #define N 400
      8 const int INF = 0x3f3f3f3f;
      9 
     10 struct Edge {
     11     int v, nxt, cap, init;
     12 }edge[N];
     13 int cur[N], dis[N], gap[N], pre[N], head[N], tot, S, T;
     14 int mp[N][N], info[N][N];
     15 
     16 void Add(int u, int v, int cap) {
     17     edge[tot].nxt = head[u]; edge[tot].v = v; edge[tot].cap = cap; edge[tot].init = cap; head[u] = tot++;
     18     edge[tot].nxt = head[v]; edge[tot].v = u; edge[tot].cap = 0; edge[tot].init = 0; head[v] = tot++;
     19 }
     20 
     21 int BFS() {
     22     queue<int> que;
     23     while(!que.empty()) que.pop();
     24     memset(dis, -1, sizeof(dis));
     25     memset(gap, 0, sizeof(gap));
     26     que.push(T); dis[T] = 0;
     27     gap[0] = 1;
     28     while(!que.empty()) {
     29         int u = que.front(); que.pop();
     30         for(int i = head[u]; ~i; i = edge[i].nxt) {
     31             int v = edge[i].v;
     32             if(~dis[v]) continue;
     33             dis[v] = dis[u] + 1;
     34             gap[dis[v]]++;
     35             que.push(v);
     36         }
     37     }
     38     return ~dis[S];
     39 }
     40 
     41 int ISAP(int n, int m) { // n = T + 1 !!!
     42     memcpy(cur, head, sizeof(cur));
     43     int ans = 0, i, u = pre[S] = S;
     44     while(dis[S] < n) {
     45         if(u == T) {
     46             int flow = INF, index = S;
     47             for(i = S; i != T; i = edge[cur[i]].v) {
     48                 if(flow > edge[cur[i]].cap) {
     49                     flow = edge[cur[i]].cap; index = i;
     50                 }
     51             }
     52             for(i = S; i != T; i = edge[cur[i]].v) {
     53                 edge[cur[i]].cap -= flow; edge[cur[i]^1].cap += flow;
     54                 int v = edge[cur[i]].v;
     55                 if(i > m && v > S && v <= m) {
     56                     mp[i-m][v] += flow;
     57                 }
     58             }
     59             ans += flow;
     60             u = index;
     61         }
     62         for(i = cur[u]; ~i; i = edge[i].nxt)
     63             if(edge[i].cap > 0 && dis[edge[i].v] + 1 == dis[u])
     64                 break;
     65         if(~i) {
     66             cur[u] = i;
     67             pre[edge[i].v] = u;
     68             u = edge[i].v;
     69         } else {
     70             if(--gap[dis[u]] == 0) break;
     71             int md = n;
     72             for(i = head[u]; ~i; i = edge[i].nxt) {
     73                 if(dis[edge[i].v] < md && edge[i].cap > 0) {
     74                     md = dis[edge[i].v]; cur[u] = i;
     75                 }
     76             }
     77             ++gap[dis[u] = md + 1];
     78             u = pre[u];
     79         }
     80     }
     81     return ans;
     82 }
     83 
     84 int main() {
     85     int n, P;
     86     while(~scanf("%d%d", &P ,&n)) {
     87         memset(head, -1, sizeof(head));
     88         memset(mp, 0, sizeof(mp));
     89         tot = 0; S = 0; T = 2 * n + 1;
     90         for(int i = 1; i <= n; i++) {
     91             scanf("%d", &info[i][0]);
     92             for(int j = 1; j <= P; j++)
     93                 scanf("%d", &info[i][j]);
     94             for(int j = 1; j <= P; j++)
     95                 scanf("%d", &info[i][j+P]);
     96         }
     97         for(int i = 1; i <= n; i++) {
     98             Add(i, i + n, info[i][0]);
     99             int fs = 1, ft = 1;
    100             for(int j = 1; j <= P; j++) {
    101                 if(info[i][j+P] == 0) ft = 0;
    102                 if(info[i][j] == 1) fs = 0;
    103             }
    104             if(fs) Add(S, i, INF);
    105             if(ft) Add(i + n, T, INF);
    106             for(int j = 1; j <= n; j++) {
    107                 fs = 1;
    108                 for(int k = 1; k <= P; k++)
    109                     if(info[j][k] != 2 && info[j][k] != info[i][k+P]) fs = 0;
    110                 if(fs) Add(i + n, j, INF);
    111             }
    112         }
    113         int ans = ISAP(T + 1, n), cnt = 0;
    114 //        for(int i = n + 1; i <= 2 * n; i++) {
    115 //            for(int j = head[i]; ~j; j = edge[j].nxt) {
    116 //                int v = edge[j].v;
    117 //                if(v > 0 && v <= n && edge[j].cap < edge[j].init) mp[i-n][v] += edge[j].init - edge[j].cap;
    118 //            }
    119 //        }
    120         for(int i = 1; i <= n; i++)
    121             for(int j = 1; j <= n; j++)
    122                 if(mp[i][j]) cnt++;
    123         printf("%d %d
    ", ans, cnt);
    124         for(int i = 1; i <= n; i++)
    125             for(int j = 1; j <= n; j++)
    126                 if(mp[i][j]) printf("%d %d %d
    ", i, j, mp[i][j]);
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    Java多线程系列 基础篇10 wait/notify/sleep/yield/join
    Java多线程系列 基础篇09 Object.wait/notifyJVM源码实现
    Java多线程系列 基础篇07 synchronized底层优化
    Java多线程系列 基础篇06 synchronized(同步锁)
    Java多线程系列 基础篇05 synchronized关键字
    Java多线程系列 基础篇04 线程中断
    Java多线程系列 基础篇03 线程的优先级和守护线程
    Java多线程系列 基础篇02 线程的创建和运行
    MySQL进阶14--标识列(自增序列/auto_increment)--设置/展示步长--设置/删除标示列
    MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6233838.html
Copyright © 2020-2023  润新知