• poj 3436 ACM Computer Factory


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

    纠结了好几天的题目,看懂题意就看了好长时间,题目大意:

    有N台机器,每台机器有P部分,每部分有自己的输入、输出,因此每台机器有2*P+1种参数:第一个参数Q:该机器的容量;接下来P个参数S:该机器各部分的输入;接下来P个参数D:该机器各部分的输出。

    其中输入有三种情况:0,1,2

    0:该部分必须不要;1:该部分必须要;2:该部分可有可无

    输出有2种情况:0,1  

    0:该部分不存在;1:该部分存在

    题目要求的是最大流、流量改变的边数和改变的边。

    思路:

    如果某个节点 u 的输入部分没有1,则添加一条 s->u 路径,容量为Qu;如果某个节点 v 输出全为1,则添加一条 v->t 路径,容量为Qv;如果节点 u 的输出与 v 的输入不冲突,则添加一条 u->v 的路径,容量为min(Qu, Qv)。

    看了一下网上的题解,基本上都是用拆点建图过的,不知道为什么,按照我的这个思路,没拆点也过了,可能数据弱?

    代码:

      1 const int maxn = 110;
      2 const int maxm = 20500;
      3 const int oo = 1<<29;
      4 struct edge{
      5     int u;
      6     int v;
      7     int w;
      8     int next;
      9     edge(){
     10         w = 0;
     11     }
     12 }edge[maxn], edge1[maxn];
     13 int n, cnt;
     14 int head[maxn], dep[maxn], gap[maxn];
     15 int s[maxn], cur[maxn], head1[maxn];
     16 
     17 void add(int u, int v, int w){
     18     edge[cnt].u = u;
     19     edge[cnt].v = v;
     20     edge[cnt].w = w;
     21     edge[cnt].next = head[u];
     22     edge1[cnt].u = u;
     23     edge1[cnt].v = v;
     24     edge1[cnt].w = w;
     25     edge1[cnt].next = head[u];
     26     head[u] = cnt++;
     27     head1[u] = cnt - 1;
     28     edge[cnt].u = v;
     29     edge[cnt].v = u;
     30     edge[cnt].w = 0;
     31     edge1[cnt].u = v;
     32     edge1[cnt].v = u;
     33     edge1[cnt].w = 0;
     34     edge1[cnt].next = head[v];
     35     edge[cnt].next = head[v];
     36     head[v] = cnt++;
     37     head1[v] = cnt - 1;
     38 }
     39 
     40 void BFS(int start, int end){
     41     int i, to, u;
     42     memset(dep, -1, sizeof(dep));
     43     memset(gap, 0, sizeof(gap));
     44     queue <int> que;
     45     dep[end] = 0;
     46     gap[0] = 1;
     47     que.push(end);
     48     while(!que.empty()){
     49         u = que.front();
     50         que.pop();
     51         for(i = head[u]; i != -1; i = edge[i].next){
     52             to = edge[i].v;
     53             if(dep[to] != -1 || edge[i].w != 0) continue;
     54             que.push(to);
     55             dep[to] = dep[u]+1;
     56             gap[dep[to]]++;
     57         }
     58     }
     59 }
     60 
     61 int sap(int start, int end){
     62     int res = 0;
     63     BFS(start, end);
     64     int u = start, top = 0;
     65     memcpy(cur, head, sizeof(head));
     66     while(dep[start] < n){
     67         if(u == end){
     68             int Min = oo, flag;
     69             for(int i = 0; i < top; i++){
     70                 if(edge[s[i]].w < Min){
     71                     Min = edge[s[i]].w;
     72                     flag = i;
     73                 }
     74             }
     75             res += Min;
     76             for(int i = 0; i < top; i++){
     77                 edge[s[i]].w -= Min;
     78                 edge[s[i]^1].w += Min;
     79             }
     80             top = flag;
     81             u = edge[s[top]].u;
     82         }
     83         if(u != end && gap[dep[u]-1] == 0) break;
     84         int i;
     85         for(i = cur[u]; i != -1; i = edge[i].next){
     86             if(edge[i].w != 0 && dep[edge[i].v]+1 == dep[u]) break;
     87         }
     88         if(i != -1){
     89             cur[u] = i;
     90             s[top++] = i;
     91             u = edge[i].v;
     92         }
     93         else{
     94             int Min = n;
     95             for(i = head[u]; i != -1; i = edge[i].next){
     96                 if(edge[i].w == 0) continue;
     97                 if(Min > dep[edge[i].v]){
     98                     cur[u] = i;
     99                     Min = dep[edge[i].v];
    100                 }
    101             }
    102             gap[dep[u]]--;
    103             dep[u] = Min+1;
    104             gap[dep[u]]++;
    105             if(u != start)
    106                 u = edge[s[--top]].u;
    107         }
    108     }
    109     return res;
    110 }
    111 
    112 void init(){
    113     cnt = 0;
    114     memset(head, -1, sizeof(head));
    115 }
    116 
    117 int main(){
    118     #ifndef ONLINE_JUDGE
    119         freopen("in.txt", "r", stdin);
    120         //freopen("out.txt", "w", stdout);
    121     #endif
    122     int p;
    123     int a[maxn], s[maxn][maxn], q[maxn][maxn];
    124     while(~scanf("%d %d", &p, &n)){
    125         init();
    126         int pr[101][3];
    127         int start , end;
    128         start = 0;
    129         end = n+1;
    130         for(int i = 1; i <= n; i++){
    131             scan_d(a[i]);
    132             for(int j = 0; j < p; j++){
    133                 scan_d(s[i][j]);
    134             }
    135             for(int j = 0; j < p; j++){
    136                 scan_d(q[i][j]);
    137             }
    138         }
    139         for(int i = 1; i <= n; i++){
    140             bool fs = true, ft = true;
    141             for(int j = 0; j < p; j++){
    142                 if(s[i][j] == 1) fs = false;
    143                 if(q[i][j] == 0) ft = false;
    144             }
    145             if(fs) {
    146                 //printf("%d %d %d\n", start, i, a[i]);
    147                 add(start, i, a[i]);
    148             }
    149             if(ft){
    150                 //printf("%d %d %d\n", i, end, a[i]);
    151                 add(i, end, a[i]);
    152             }
    153             bool fc = true;
    154             for(int j = 1; j <= n; j++){
    155                 if(i != j){
    156                     fc = true;
    157                     for(int k = 0; k < p && fc; k++){
    158                         if(q[i][k] + s[j][k] == 1) fc = false; 
    159                     }
    160                     if(fc){
    161                         //printf("%d %d %d\n", i, j, min(a[i], a[j]));
    162                         add(i, j, min(a[i], a[j]));
    163                     }
    164                 }
    165             }
    166         }
    167         n += 2;
    168         int res = sap(start, end);
    169         //cout << res << endl;
    170         int numb = 0;
    171         for(int i = 0; i <= cnt; i++){
    172             if(edge[i].w < edge1[i].w && edge[i].u!=0 && edge[i].v!=n-1){
    173                 pr[numb][0] = edge[i].u;
    174                 pr[numb][1] = edge[i].v;
    175                 pr[numb++][2] =  edge1[i].w - edge[i].w;
    176             }
    177         }
    178         printf("%d %d\n", res, numb);
    179         for(int i = 0; i < numb; i++){
    180             printf("%d %d %d\n", pr[i][0], pr[i][1], pr[i][2]);
    181         }
    182     }
    183     return 0;
    184 }
  • 相关阅读:
    Python笔试题(递归)
    MYSQL经典面试题
    Linux常用命令
    HTTP协议相关面试题
    Flask面试题
    史上最全DVWA 笔记
    ssh root Permission denied
    odoo Reference 选择model 然后选择record
    定体, 定压, 定温, 绝热 Q E A 公式
    Vmware Bluetooth
  • 原文地址:https://www.cnblogs.com/pony1993/p/2807262.html
Copyright © 2020-2023  润新知