hdu 4971
来源:互联网 发布:下载贵金属软件 编辑:程序博客网 时间:2024/06/06 17:43
经典闭权和问题,正权的点由源点向该点连边,负权的点由该点向负权连边,做最大流,找到最小割即可,然后由正权点权和减去最小割容量。
AC代码:
#include <cstdio>#include <cstring>#include <map>#include <vector>#include <algorithm>using namespace std;const int maxn = 10007;const int INF = 10000007;int n, m;int head[maxn], edge_number, cur[maxn], dist[maxn], s[maxn], que[maxn], source, dest, flow;struct Edge { int u, v, cap, next;};struct Edge edge[maxn];void addEdge(int u, int v, int cap) { edge[edge_number].u = u; edge[edge_number].v = v; edge[edge_number].cap = cap; edge[edge_number].next = head[u]; head[u] = edge_number; edge_number++; edge[edge_number].u = v; edge[edge_number].v = u; edge[edge_number].cap = 0; edge[edge_number].next = head[v]; head[v] = edge_number; edge_number++;}int bfs() { int front = 0; int rear = 1; memset(dist, -1, sizeof(dist)); dist[source] = 0; que[front] = source; while (front < rear) { int cnt = que[front]; for (int i = head[cnt]; i != -1; i = edge[i].next) { int v = edge[i].v; if (edge[i].cap > 0 && dist[v] == -1) { dist[v] = dist[cnt] + 1; que[rear++] = v; if (v == dest) { return 1; } } } front++; } return 0;}int dinic() { int top, cnt, min_flow, min_flow_num, flow; flow = 0; while (bfs()) { memcpy(cur, head, sizeof(cur)); top = 0; cnt = source; while (1) { if (cnt == dest) { min_flow = INF; for (int i = 0; i < top; i++) { if (edge[s[i]].cap < min_flow) { min_flow = edge[s[i]].cap; min_flow_num = i; } } for (int i = 0; i < top; i++) { edge[s[i]].cap -= min_flow; edge[s[i] ^ 1].cap += min_flow; } flow += min_flow; top = min_flow_num; cnt = edge[s[top]].u; } for (int i = cur[cnt]; i != -1; cur[cnt] = i = edge[i].next) { if (edge[i].cap > 0 && dist[edge[i].v] == dist[cnt] + 1) { break; } } if (cur[cnt] != -1) { s[top++] = cur[cnt]; cnt = edge[cur[cnt]].v; } else { if (top == 0) { break; } dist[cnt] = -1; top--; cnt = edge[s[top]].u; } } } return flow;}int main() {// freopen("in.txt", "r", stdin); int test_case; scanf("%d", &test_case); int ncase = 1; while (test_case--) { edge_number = 0; memset(head, -1, sizeof(head)); scanf("%d%d", &n, &m); int sums = 0; source = 0; dest = n + m + 1; for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); addEdge(source, i, x); sums += x; } for (int i = 1; i <= m; i++) { int x; scanf("%d", &x); addEdge(n + i, dest, x); } for (int i = 1; i <= n; i++) { int a; scanf("%d", &a); for (int j = 1; j <= a; j++) { int c; scanf("%d", &c); addEdge(i, n + 1 + c, INF); } } for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { int x; scanf("%d", &x); if (x == 1) { addEdge(n + 1 + i, n + 1 + j, INF); } } } int ans = dinic(); printf("Case #%d: %d\n", ncase, sums - ans); ncase++; } return 0;}
0 0
- hdu 4971
- hdu 4971
- hdu 4971
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- SQL Server -为代码减负之触发器
- 跨服务器修改数据
- QT之父子对象机制
- js中document.write的那点事
- Java Observer pattern 实例 , 用于 monitor
- hdu 4971
- JAVA多线程变量的深入认识(二)
- Java分块传输的思路
- servlet filter listener interceptor 作用和区别
- POJ 1273 Drainage Ditches
- 去掉文件中^M的方法
- hdu 4960 Another OCD Patient dp
- 跨服务器操作数据库
- PHP盛宴——常用函数集锦