• ZOJ 2601 Warehouse Keeper


    Warehouse Keeper

    Time Limit: 2000ms
    Memory Limit: 65536KB
    This problem will be judged on ZJU. Original ID: 2601
    64-bit integer IO format: %lld      Java class name: Main
    Special Judge
     

    The company where Jerry works owns a number of warehouses that can be used to store various goods. For each warehouse the types of goods that can be stored in this warehouse are known. To avoid problems with taxes, each warehouse must store only one type of goods, and each type of goods must be stored in at most one warehouse.

    Jerry is planning to receive a new lot of goods in a couple of days and he must store the goods in the warehouses. However there are some goods in some warehouses already and Jerry wants to move as few of them as possible.

    Help him to find the maximal number of types of goods that he can store in the warehouses and the minimal number of goods he must move in order to do that.


    Input

    The input contains multiple test cases. The first line of the input is a single integer T (1 <= T <= 40) which is the number of test cases. T test cases follow, each preceded by a single blank line.

    The first line of each test case contains integer numbers m and n (2 <= m, n <= 200) - the number of warehouses and the number of types of goods respectively.

    The following m lines describe warehouses. Each line contains ki - the number of various types of goods that can be stored in this warehouse (remember, only one type of goods can be stored in a warehouse at a time), followed by ki integer numbers - the types of goods that can be stored.

    The last line contains m integer numbers - for each warehouse either 0 is provided if there is no goods in this warehouse, or the type of goods that is currently stored in this warehouse if there is one. It is guaranteed that the initial configuration is correct, that is, each warehouse stores the goods it can store, and no type of goods is stored in more than one warehouse.


    Output

    For each case, on the first line print p - the maximal number of types of goods that can be stored in the warehouses, and q - the minimal number of goods that need to be moved in order to do that. After that output m integer numbers - for each warehouse output the type of goods that must be stored in this warehouse, or 0 if none must be.

    Remember that you may only move goods that are already stored in some houses to other ones, you are not allowed to dispose them.

    Two consecutive cases should be separated by a single blank line. No blank line should be produced after the last test case.


    Sample Input

    2
    
    4 5
    3 1 2 3
    2 1 2
    2 1 2
    3 1 4 5
    0 2 0 1
    
    2 2
    1 1
    1 2
    0 0
    

    Sample Output

    4 1
    3 2 1 4
    
    2 0
    1 2 
    

     

    Source

    Author

    Andrew Stankevich
     
    解题:费用流
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <climits>
      7 #include <vector>
      8 #include <queue>
      9 #include <cstdlib>
     10 #include <string>
     11 #include <set>
     12 #include <stack>
     13 #define LL long long
     14 #define INF 0x3f3f3f3f
     15 #define pii pair<int,int>
     16 using namespace std;
     17 const int maxn = 500;
     18 struct arc{
     19     int to,flow,cost,next;
     20     arc(int x = 0,int y = 0,int z = 0,int nxt = -1){
     21         to = x;
     22         flow = y;
     23         cost = z;
     24         next = nxt;
     25     }
     26 };
     27 arc e[maxn*maxn];
     28 int head[maxn],d[maxn],p[maxn],house[maxn];
     29 int tot,S,T,n,m;
     30 bool in[maxn];
     31 int vis[maxn];
     32 vector<int>g[maxn];
     33 void add(int u,int v,int flow,int cost){
     34     e[tot] = arc(v,flow,cost,head[u]);
     35     head[u] = tot++;
     36     e[tot] = arc(u,0,-cost,head[v]);
     37     head[v] = tot++;
     38 }
     39 bool spfa(){
     40     queue<int>q;
     41     for(int i = S; i <= T; ++i){
     42         d[i] = INF;
     43         in[i] = false;
     44         p[i] = -1;
     45     }
     46     d[S] = 0;
     47     q.push(S);
     48     while(!q.empty()){
     49         int u = q.front();
     50         q.pop();
     51         in[u] = false;
     52         for(int i = head[u]; ~i; i = e[i].next){
     53             if(e[i].flow && d[e[i].to] > d[u] + e[i].cost){
     54                 d[e[i].to] = d[u] + e[i].cost;
     55                 p[e[i].to] = i;
     56                 if(!in[e[i].to]){
     57                     in[e[i].to] = true;
     58                     q.push(e[i].to);
     59                 }
     60             }
     61         }
     62     }
     63     return p[T] > -1;
     64 }
     65 int solve(int &cost){
     66     int flow = cost = 0;
     67     while(spfa()){
     68         int minF = INF;
     69         for(int i = p[T]; ~i; i = p[e[i^1].to])
     70             minF = min(minF,e[i].flow);
     71         for(int i = p[T]; ~i; i = p[e[i^1].to]){
     72             e[i].flow -= minF;
     73             e[i^1].flow += minF;
     74         }
     75         cost += minF*d[T];
     76         flow += minF;
     77     }
     78     return flow;
     79 }
     80 int main(){
     81     int cs,u;
     82     scanf("%d",&cs);
     83     bool cao = false;
     84     while(cs--){
     85         if(cao) puts("");
     86         cao = true;
     87         memset(head,-1,sizeof(head));
     88         memset(house,0,sizeof(house));
     89         memset(vis,0,sizeof(vis));
     90         scanf("%d %d",&m,&n);
     91         S = tot = 0;
     92         T = n + m + 1;
     93         for(int i = 0; i <= T; ++i) g[i].clear();
     94         for(int i = 1; i <= m; ++i){
     95             int tmp = 0;
     96             scanf("%d",&tmp);
     97             while(tmp--){
     98                 scanf("%d",&u);
     99                 g[i].push_back(u);
    100             }
    101         }
    102         for(int i = 1; i <= m; ++i){
    103             scanf("%d",house+i);
    104             vis[house[i]] = i;
    105         }
    106         for(int i = 1; i <= m; ++i){
    107             for(int j = g[i].size()-1; j >= 0; --j){
    108                 int tmp = g[i][j];
    109                 if(vis[tmp] == i) add(i,tmp+m,1,0);
    110                 else if(vis[tmp] && vis[tmp] != i) add(i,tmp+m,1,1);
    111                 else add(i,tmp+m,1,0);
    112             }
    113         }
    114         for(int i = 1; i <= m; ++i)
    115             add(S,i,1,0);
    116         for(int i = 1; i <= n; ++i)
    117             add(i+m,T,1,vis[i]?-10:0);
    118         int ans,cost;
    119         ans = solve(cost);
    120         int ahouse[maxn],mb = 0;
    121         memset(ahouse,0,sizeof(ahouse));
    122         for(int i = 0; i < tot; i += 2){
    123             if(e[i].to == T  || e[i^1].to == S ) continue;
    124             if(e[i].flow == 0) ahouse[e[i^1].to] = e[i].to-m;//cout<<e[i^1].to<<" "<<e[i].to-m<<endl;
    125         }
    126         for(int i = 1; i <= m; ++i)
    127             if(house[i] && ahouse[i] != house[i]) mb++;
    128         printf("%d %d
    ",ans,mb);
    129         for(int i = 1; i <= m; ++i)
    130             printf("%d%c",ahouse[i],i == m ?'
    ':' ');
    131     }
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    【转载】Modelsim之 DO文件简介
    【原创】Quartus与Modelsim的联合仿真及脚本
    【原创】Quartus II 简单设计流程
    【原创】Modelsim仿真简单流程
    【原创】静态时序分析整理一
    【原创】DC的一些命令
    【转载】建立时间与保持时间
    linux 创建链接命令 ln -s 软链接
    Vim常用命令
    gvim查找与替换命令
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4065454.html
Copyright © 2020-2023  润新知