给你一些东西, 每个东西有一个值,有正有负。 在给一些关系, 选了其中一个物品, 和他有关系的也必须全都选上, 关系是单向的。 问最后的最大价值是多少, 如果小于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\n", 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 }