zoukankan      html  css  js  c++  java
  • POJ3436

    题目链接:http://poj.org/problem?id=3436

    题目大意:

      一台电脑可以分成P个部分,在生产过程中,半成品电脑有的部分已经完成(记为1),而有的部分还没有完成(记为0)。电脑生产商用N台机器生产电脑,对于放入各台机器的电脑,各自有其要求,即有些部分必须已经完成(记为1),有些部分必须还未完成(记为0),有些部分是否完成无关紧要(记为2),求怎么安排生产线使工厂的总生产效率最高。

    解题思路:

      最大流问题。

      首先是建图。如果某台机器对于放入其中的电脑的要求全为0或者2,那么这台机器就是一个源点,如果某台机器生产出的电脑所有部分都为1,那么这台机器就可以看成一个汇点。这样就有多个源点和多个汇点,那么我们可以设置一个超级源点和超级汇点,超级源点指向每一个源点,每一个汇点指向超级汇点,流量限制为inf。对于每一台机器,为了表示其效率上限,我们将其拆成两个点,表示入口和出口,中间用一条流量限制为机器生存效率的线连接。而对于不同的机器,如果一台机器生产出来的电脑能够送往另一台电脑,那么就将这台机器的出口指向另一台机器的入口,流量限制为inf。建图完成,其他的交给模板。

      另一个难点是要printf出最大流经过的路径。那么我们就可以来研究模板跑完以后留下的残量网络。首先有三种路是我们为了方便解决问题而加入的,printf路径的时候必须无视掉:从超级源点流出的路,流入超级汇点的路,由机器入口流到出口的路。那么对于剩下的路,如果路上流量大于0,(或者说残量小于流量限制),那么这条路就是我们这个最大流网络中会经过的,打印出起点、终点和流量即可。

    AC代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <cstring>
      5 #include <queue>
      6 using namespace std;
      7 const int inf = 0x7ffffff, maxn = 100 + 5;
      8 struct node {
      9     int s[12], t[12];
     10     int v;
     11 }machine[55];
     12 //模板作者:刘汝佳
     13 //**************************************************
     14 struct ans {
     15     int from, to, num;
     16 }ret[maxn];
     17 struct Edge {
     18     int from, to, cap, flow;
     19     Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f) {}
     20 };
     21 vector<int>ans[maxn];
     22 int len = 0, dis[maxn][maxn];
     23 struct Dinic {
     24     int n, m, s, t;
     25     vector<Edge> edges;
     26     vector<int> G[maxn];
     27     bool vis[maxn];
     28     int d[maxn];
     29     int cur[maxn];
     30 
     31     void init(int n) {
     32         this->n = n;
     33         for (int i = 0; i < n; i++)    G[i].clear();
     34         edges.clear();
     35     }
     36     void addedge(int from, int to, int cap) {
     37         edges.push_back(Edge(from, to, cap, 0));
     38         edges.push_back(Edge(to, from, 0, 0));
     39         m = edges.size();
     40         G[from].push_back(m - 2);
     41         G[to].push_back(m - 1);
     42     }
     43     bool BFS() {
     44         memset(vis, 0, sizeof(vis));
     45         queue<int> Q;
     46         Q.push(s);
     47         d[s] = 0;
     48         vis[s] = 1;
     49         while (!Q.empty()) {
     50             int x = Q.front();    Q.pop();
     51             for (int i = 0; i < G[x].size(); i++) {
     52                 Edge &e = edges[G[x][i]];
     53                 if (!vis[e.to] && e.cap>e.flow) {
     54                     vis[e.to] = 1;
     55                     d[e.to] = d[x] + 1;
     56                     Q.push(e.to);
     57                 }
     58             }
     59         }
     60         return vis[t];
     61     }
     62     int DFS(int x, int a) {
     63         if (x == t || a == 0)    return a;
     64         int flow = 0, f;
     65         for (int &i = cur[x]; i < G[x].size(); i++) {
     66             Edge &e = edges[G[x][i]];
     67             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0) {
     68                 e.flow += f;
     69                 edges[G[x][i] ^ 1].flow -= f;
     70                 flow += f;
     71                 a -= f;
     72                 if (a == 0)    break;
     73             }
     74         }
     75         return flow;
     76     }
     77     int Maxflow(int s, int t) {
     78         this->s = s;    this->t = t;
     79         int flow = 0;
     80         while (BFS()) {
     81             memset(cur, 0, sizeof(cur));
     82             flow += DFS(s, inf);
     83         }
     84         return flow;
     85     }
     86 };
     87 //****************************************************
     88 int main() {
     89     //    freopen("in.txt","r",stdin);
     90     int P, N;
     91     Dinic temp;
     92     scanf("%d%d", &P, &N);
     93     temp.init(2 * N + 2);
     94     for (int i = 1; i <= N; i++) {
     95         scanf("%d", &machine[i].v);
     96         for (int j = 0; j<P; j++)    scanf("%d", &machine[i].s[j]);
     97         for (int j = 0; j<P; j++)    scanf("%d", &machine[i].t[j]);
     98         bool sour = true;
     99         for (int j = 0; j<P; j++) {
    100             if (machine[i].s[j] == 1) {
    101                 sour = false;
    102                 break;
    103             }
    104         }
    105         if (sour)    temp.addedge(0, i, inf);
    106         bool ending = true;
    107         for (int j = 0; j<P; j++) {
    108             if (machine[i].t[j] != 1) {
    109                 ending = false;
    110                 break;
    111             }
    112         }
    113         if (ending)  temp.addedge(i + N, 2 * N + 1, inf);
    114         temp.addedge(i, i + N, machine[i].v);
    115     }
    116     for (int i = 1; i <= N; i++) {
    117         for (int j = i + 1; j <= N; j++) {
    118             bool yes1 = true, yes2 = true;
    119             for (int k = 0; k<P; k++) {
    120                 if (machine[i].t[k]) {
    121                     if (machine[j].s[k] == 0)  yes1 = false;
    122                 }
    123                 else {
    124                     if (machine[j].s[k] == 1)  yes1 = false;
    125                 }
    126                 if (machine[j].t[k]) {
    127                     if (machine[i].s[k] == 0)  yes2 = false;
    128                 }
    129                 else {
    130                     if (machine[i].s[k] == 1)  yes2 = false;
    131                 }
    132                 if (!yes1&&!yes2)    break;
    133             }
    134             if (yes1)
    135                 temp.addedge(i + N, j, inf);
    136             if (yes2)
    137                 temp.addedge(j + N, i, inf);
    138         }
    139     }
    140     printf("%d ", temp.Maxflow(0, 2 * N + 1));
    141     int cnt = 0;
    142 
    143     for (int i = 0; i<temp.edges.size(); i++) {
    144         Edge t = temp.edges[i];
    145         int fw = t.flow, f = t.from, tt = t.to;
    146         if (fw <= 0 || t.cap == 0 || t.cap != inf || tt>N || f<1)  continue;
    147         ret[cnt].from = f - N, ret[cnt].to = tt, ret[cnt].num = fw;
    148         cnt++;
    149     }
    150     printf("%d
    ", cnt);
    151     for (int i = 0; i<cnt; i++) {
    152         printf("%d %d %d
    ", ret[i].from, ret[i].to, ret[i].num);
    153     }
    154     return 0;
    155 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    做了半年的答题小程序上线了
    党建答题助手小程序
    党建答题活动小程序
    微信答题活动小程序
    微信答题活动小程序
    如何搭建在线考试小程序
    如何搭建在线考试小程序
    基于云开发的在线答题小程序
    XLua访问C#中的List或者数组
    字符串、字节数组、流之间的相互转换以及文件MD5的计算
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7423972.html
Copyright © 2011-2022 走看看