• zoj 2071 Technology Trader 最大权闭合子图


    传送门

    和上一题一样, 也是一个最大权闭合子图。不过建图好麻烦的感觉  写了好久。

    源点和原材料连边, 权值为val。 汇点和产品连边, 权值为val。 产品与和它有关系的材料连边, 权值inf。 最后跑一边网络流, 满流的话是没利润的, 输出结果是利润和-最大流。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define pb(x) push_back(x)
      4 #define ll long long
      5 #define mk(x, y) make_pair(x, y)
      6 #define lson l, m, rt<<1
      7 #define mem(a) memset(a, 0, sizeof(a))
      8 #define rson m+1, r, rt<<1|1
      9 #define mem1(a) memset(a, -1, sizeof(a))
     10 #define mem2(a) memset(a, 0x3f, sizeof(a))
     11 #define rep(i, a, n) for(int i = a; i<n; i++)
     12 #define ull unsigned long long
     13 typedef pair<int, int> pll;
     14 const double PI = acos(-1.0);
     15 const double eps = 1e-8;
     16 const int mod = 1e9+7;
     17 const int inf = 1061109567;
     18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
     19 const int maxn = 20000;
     20 int head[maxn*4], s, t, num, q[maxn*10], dis[maxn], used[maxn], cnt1, cnt2, ans1[maxn], ans2[maxn];
     21 map <string, int> vis;
     22 struct
     23 {
     24     int val;
     25     string name;
     26 }a[maxn];
     27 struct node
     28 {
     29     int to, nextt, c;
     30 }e[maxn*4];
     31 void init() {
     32     mem1(head);
     33     num = cnt1 = cnt2 = 0;
     34     mem(used);
     35     vis.clear();
     36 }
     37 void add(int u, int v, int c) {
     38     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
     39     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
     40 }
     41 int bfs() {
     42     int u, v, st = 0, ed = 0;
     43     mem(dis);
     44     dis[s] = 1;
     45     q[ed++] = s;
     46     while(st<ed) {
     47         u = q[st++];
     48         for(int i = head[u]; ~i; i = e[i].nextt) {
     49             v = e[i].to;
     50             if(e[i].c&&!dis[v]) {
     51                 dis[v] = dis[u]+1;
     52                 if(v == t)
     53                     return 1;
     54                 q[ed++] = v;
     55             }
     56         }
     57     }
     58     return 0;
     59 }
     60 int dfs(int u, int limit) {
     61     if(u == t)
     62         return limit;
     63     int cost = 0;
     64     for(int i = head[u]; ~i; i = e[i].nextt) {
     65         int v = e[i].to;
     66         if(e[i].c&&dis[u] == dis[v]-1) {
     67             int tmp = dfs(v, min(limit-cost, e[i].c));
     68             if(tmp>0) {
     69                 e[i].c -= tmp;
     70                 e[i^1].c += tmp;
     71                 cost += tmp;
     72                 if(cost == limit)
     73                     break;
     74             } else {
     75                 dis[v] = -1;
     76             }
     77         }
     78     }
     79     return cost;
     80 }
     81 int dinic() {
     82     int ans = 0;
     83     while(bfs()) {
     84         ans += dfs(s, inf);
     85     }
     86     return ans;
     87 }
     88 void dfs(int u) {
     89     used[u] = 1;
     90     for(int i = head[u]; ~i; i = e[i].nextt) {
     91         int v = e[i].to;
     92         if(e[i].c&&!used[v]) {
     93             dfs(v);
     94         }
     95     }
     96 }
     97 int main()
     98 {
     99     int T, n, q, val, x;
    100     cin>>T;
    101     while(T--) {
    102         cin>>n;
    103         init();
    104         s = 0;
    105         int i, sum = 0;
    106         for(i = 1; i<=n; i++) {
    107             cin>>a[i].name>>a[i].val;
    108             vis[a[i].name] = i;
    109             add(s, i, a[i].val);
    110         }
    111         cin>>q;
    112         t = n+q+1;
    113         string str;
    114         while(q--) {
    115             cin>>a[i].name>>a[i].val>>x;
    116             sum += a[i].val;
    117             add(i, t, a[i].val);
    118             while(x--) {
    119                 cin>>str;
    120                 add(vis[str], i, inf);
    121             }
    122             i++;
    123         }
    124         int ans =  sum - dinic();
    125         dfs(0);
    126         for(int i = head[s]; ~i; i = e[i].nextt) {
    127             int v = e[i].to;
    128             if(!used[v]) {
    129                 ans1[cnt1++] = v;
    130             }
    131         }
    132         for(int i = head[t]; ~i; i = e[i].nextt) {
    133             int v = e[i].to;
    134             if(!used[v]) {
    135                 ans2[cnt2++] = v;
    136             }
    137         }
    138         cout<<ans<<endl;
    139         cout<<cnt2<<endl;
    140         for(int i = 0; i<cnt2; i++) {
    141             cout<<a[ans2[i]].name<<endl;
    142         }
    143         cout<<cnt1<<endl;
    144         for(int i = 0; i<cnt1; i++)
    145             cout<<a[ans1[i]].name<<endl;
    146     }
    147 }
  • 相关阅读:
    接口和抽象类的异同点
    实体对象间传值克隆
    什么是反射&反射的8个类的用法
    ERP中反射的两个实例
    基础02 Java 跨平台原理
    基础01 dos命令
    lists删除
    多字段 java对象排序
    Java对象排序
    MySQL表中数据的迁移
  • 原文地址:https://www.cnblogs.com/yohaha/p/5010916.html
Copyright © 2020-2023  润新知