hihocoder1393(二分图多重匹配)
来源:互联网 发布:德云社 知乎 编辑:程序博客网 时间:2024/06/06 22:24
题目
是一个裸地二分图多重匹配,但是做法十分粗糙,强行遍历了0-500,如果是普通的方法会TLE,用了ISAP实现。晚一些改一下。
感觉多重匹配和最大匹配的差别在于一个点能否使用多次。也就是边权是否为1。(但是感觉有什么地方不大对)
#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;//点数的最大值const int MAXM = 400010;//边数的最大值const int INF = 0x3f3f3f3f;struct Edge{ int to,next,cap,flow;} edge[MAXM]; //注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN],n,m;void init(){ tol = 0; memset(head,-1,sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,int w,int rw=0){ edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u]; edge[tol].flow = 0; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].next = head[v]; edge[tol].flow = 0; head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数int sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; for(int i = pre[u]; i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if(flag) { u = v; continue; } int Min = N; for(int i = head[u]; i != -1; i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min+1; gap[dep[u]]++; if(u != start) u = edge[pre[u]^1].to; } return ans;}int main(){ int t,sum,temp; scanf("%d",&t); while (t--) { sum=0; init(); scanf("%d %d",&n,&m); for (int i = 1; i <= m; i++) { scanf("%d",&temp); addedge(i+100,500,temp); sum += temp; } for(int i = 1; i <= n; i++) { int t1,t2; scanf("%d %d",&t1,&t2); addedge(0,i,t1); for(int j =0; j < t2; j++) { scanf("%d",&temp); addedge(i,temp+100,1); } } if (sum == sap(0,500,500)) printf("Yes\n"); else printf("No\n"); } return 0;}
阅读全文
0 0
- hihocoder1393(二分图多重匹配)
- hihocoder1393 网络流之二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配
- 二分图多重匹配(HDU 2255)
- 二分图多重匹配问题
- 二分图的多重匹配
- 二分图多重匹配--poj2289
- 二分图多重匹配--poj2584
- 二分图的多重匹配
- 二分图多重匹配问题
- 二分图多重匹配问题
- poj2112二分图多重匹配
- GPIO原理
- MySQL Query Cache 看上去很美
- Android蓝牙(二)
- DB Link导致SCN Headroom过低问题研究
- 记录一次重构
- hihocoder1393(二分图多重匹配)
- 解决Git push时重复输入用户名密码的问题。
- Android四大图片缓存(Imageloader,Picasso,Glide,Fresco)原理、特性对比
- GAN在目标检测应用
- js省市区下拉代码分享
- RecycleView的使用
- POJ 1189 钉子和小球
- Coursera吴恩达《神经网络与深度学习》课程笔记(2)-- 神经网络基础之逻辑回归
- matlab 矩阵开n次方根