博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Bob]Collectors Problem
阅读量:5351 次
发布时间:2019-06-15

本文共 2762 字,大约阅读时间需要 9 分钟。

网络流

1.Bob向他有的贴纸连边,流量为他有的贴纸数量

2.每一种贴纸向汇点连流量为1的边

3.其余人,如果没贴纸i,由i向这个人连一条流量为1的边

4.如果贴纸i数量>1,由这个人向i连一条流量为数量-1的边

#include 
#include
#include
using namespace std;const int N = 45;const int M = 650;#define gc getchar()#define oo 999999999int n, m, now, S, T, TI;int head[N], now_head[N], calc[N], dis[N];struct Node{ int u, v, flow, nxt;}G[M];queue
Q;inline int read(){ int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}inline void add(int u, int v, int flow){ G[now].v = v; G[now].flow = flow; G[now].nxt = head[u]; head[u] = now ++;}inline bool bfs(){ for(int i = S; i <= T; i ++) now_head[i] = head[i], dis[i] = -1; dis[S] = 0; while(!Q.empty()) Q.pop(); Q.push(S); while(!Q.empty()){ int topp = Q.front(); Q.pop(); for(int i = head[topp]; ~ i; i = G[i].nxt){ int v = G[i].v; if(dis[v] == -1 && G[i].flow > 0){ dis[v] = dis[topp] + 1; if(v == T) return 1; Q.push(v); } } } return 0;}int dfs(int now, int flow){ if(now == T) return flow; int ret = 0; for(int & i = now_head[now]; ~ i; i = G[i].nxt){ int v = G[i].v; if(dis[v] == dis[now] + 1 && G[i].flow > 0){ int f = dfs(v, min(G[i].flow, flow - ret)); if(f) {G[i].flow -= f; G[i ^ 1].flow += f; ret += f; if(ret == flow) break;} } } if(ret != flow) dis[now] = -1; return ret;}inline int Dinic(){ int ret = 0; while(bfs()) ret += dfs(S, oo); return ret;}int main(){ TI = read(); for(int Ti = 1; Ti <= TI; Ti ++){ n = read(); m = read(); now = 0; T = n + m + 1; S = 1; for(int i = 0; i <= T; i ++) head[i] = -1; for(int i = 1; i <= m; i ++) add(n + i, T, 1), add(T, n + i, 0); int k = read(); for(int i = 1; i <= k; i ++){
int im = read(); calc[im] ++;} for(int i = 1; i <= m; i ++) if(calc[i]) add(1, n + i, calc[i]), add(n + i, 1, 0); for(int i = 1; i <= m; i ++) calc[i] = 0; for(int i = 2; i <= n; i ++){ int k = read(); for(int j = 1; j <= k; j ++){
int im = read(); calc[im] ++;} for(int j = 1; j <= m; j ++) if(calc[j] > 1) add(i, n + j, calc[j] - 1), add(n + j, i, 0); else if(!calc[j]) add(n + j, i, 1), add(i, n + j, 0); for(int j = 1; j <= m; j ++) calc[j] = 0; } int answer = Dinic(); printf("Case #%d: %d\n", Ti, answer); } return 0;}/*22 56 1 1 1 1 1 13 1 2 23 54 1 2 1 13 2 2 25 1 3 4 4 3*/

 

转载于:https://www.cnblogs.com/shandongs1/p/8097460.html

你可能感兴趣的文章
jmeter多线程组间的参数传递
查看>>
零散笔记
查看>>
MaiN
查看>>
[Python学习] 简单网络爬虫抓取博客文章及思想介绍
查看>>
触发器课程SQL Server 知识梳理九 触发器的使用
查看>>
信息浏览器从Android的浏览器中传递cookie数据到App中信息浏览器
查看>>
客户端连接linux虚拟机集群报错
查看>>
linux下部署一个JavaEE项目的简单步骤
查看>>
hash储存机制
查看>>
[Android学习系列16]Android把php输出的json加载到listview
查看>>
20145205 《信息安全系统设计基础》第14周学习总结
查看>>
6)添加一个窗口的图标
查看>>
POJ - 1422 Air Raid 二分图最大匹配
查看>>
Road Map
查看>>
正则替换中的一个Bug
查看>>
HI3531uboot开机画面 分类: arm-linux-Ubunt...
查看>>
制作U盘启动CDLinux 分类: 生活百科 ...
查看>>
strcpy函数里的小九九
查看>>
搭建ssm过程中遇到的问题集
查看>>
OpenLayers绘制图形
查看>>