TJU 2944 Mussy Paper 最大权闭合子图

传送门

给你一些东西,  每个东西有一个值,有正有负。 在给一些关系, 选了其中一个物品, 和他有关系的也必须全都选上, 关系是单向的。 问最后的最大价值是多少, 如果小于0输出“   **** ”(记不得是什么了。

网络流, 如果一个东西的价值是正的, 源点向它连边, 权值为val; 如果是负的, 汇点向它连边, 权值为-val。 如果1->2, 就从1向2连边, 权值为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 = 20005;
 20 int head[maxn*4], s, t, num, q[maxn*10], dis[maxn], cnt, vis[maxn];
 21 struct node
 22 {
 23     int to, nextt, c;
 24 }e[maxn*4];
 25 void init() {
 26     mem1(head);
 27     num = cnt = 0;
 28     mem(vis);
 29 }
 30 void add(int u, int v, int c) {
 31     e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++;
 32     e[num].to = u; e[num].nextt = head[v]; e[num].c = 0; head[v] = num++;
 33 }
 34 int bfs() {
 35     int u, v, st = 0, ed = 0;
 36     mem(dis);
 37     dis[s] = 1;
 38     q[ed++] = s;
 39     while(st<ed) {
 40         u = q[st++];
 41         for(int i = head[u]; ~i; i = e[i].nextt) {
 42             v = e[i].to;
 43             if(e[i].c&&!dis[v]) {
 44                 dis[v] = dis[u]+1;
 45                 if(v == t)
 46                     return 1;
 47                 q[ed++] = v;
 48             }
 49         }
 50     }
 51     return 0;
 52 }
 53 int dfs(int u, int limit) {
 54     if(u == t)
 55         return limit;
 56     int cost = 0;
 57     for(int i = head[u]; ~i; i = e[i].nextt) {
 58         int v = e[i].to;
 59         if(e[i].c&&dis[u] == dis[v]-1) {
 60             int tmp = dfs(v, min(limit-cost, e[i].c));
 61             if(tmp>0) {
 62                 e[i].c -= tmp;
 63                 e[i^1].c += tmp;
 64                 cost += tmp;
 65                 if(cost == limit)
 66                     break;
 67             } else {
 68                 dis[v] = -1;
 69             }
 70         }
 71     }
 72     return cost;
 73 }
 74 int dinic() {
 75     int ans = 0;
 76     while(bfs()) {
 77         ans += dfs(s, inf);
 78     }
 79     return ans;
 80 }
 81 void dfs(int u) {
 82     vis[u] = 1;
 83     cnt++;
 84     for(int i = head[u]; ~i; i = e[i].nextt) {
 85         int v = e[i].to;
 86         if(e[i].c&&!vis[v]) {
 87             dfs(v);
 88         }
 89     }
 90 }
 91 int main()
 92 {
 93     int n;
 94     while(scanf("%d", &n)&&n) {
 95         s = 0, t = n+1;
 96         init();
 97         int sum = 0, val, p;
 98         for(int i = 1; i<=n; i++) {
 99             scanf("%d%d", &val, &p);
100             if(val>0) {
101                 add(s, i, val);
102                 sum += val;
103             }else if(val<0) {
104                 add(i, t, -val);
105             }
106             while(p--) {
107                 scanf("%d", &val);
108                 add(i, val, inf);
109             }
110         }
111         int ans = dinic();
112         if(ans == sum) {
113             puts("Refused");
114         } else {
115             dfs(0);
116             printf("%d %d
", sum-ans, --cnt);
117             for(int i = 1; i<=n; i++) {
118                 if(vis[i]) {
119                     cnt--;
120                     printf("%d", i);
121                     if(cnt)
122                         cout<<" ";
123                     else
124                         cout<<endl;
125                 }
126             }
127         }
128     }
129 }
原文地址:https://www.cnblogs.com/yohaha/p/5009838.html