二分匹配传送门[here]

原题传送门[here]


  题意大概说一下,就是有N头牛和M个牛棚,每头牛愿意住在一些牛棚,求最大能够满足多少头牛的要求。

  很明显就是一道裸裸的二分图最大匹配,但是为了练练网络流(做其它的题的时候,神奇地re掉了,于是就写基础题了)的最大流算法,就做做这道题。

  每一个牛都可一看成是个源点,每一个牛棚都可以看成是个汇点,但是一个网络应该只有一个汇点和一个源点才对,于是构造一个连接每个牛的超级源点,一个连接每个牛棚的超级汇点,每条边的容量为1,然后最大流Dinic算法(其它最大流算法也行)就行了。

Code极其不简洁的代码

 /**
* poj.org
* Problem#1274
* Accepted
* Time:16ms
* Memory:1980k
*/
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
#define INF 0xfffffff
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && ~x);
if(!(~x)) return false;
if(x == '-'){
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
}
///map template starts
typedef class Edge{
public:
int end;
int next;
int cap;
int flow;
Edge(const int end = , const int next = , const int cap = , const int flow = ):end(end), next(next), cap(cap), flow(flow){}
}Edge; typedef class MapManager{
public:
int ce;
int *h;
Edge *edge;
MapManager(){}
MapManager(int points, int limit):ce(){
h = new int[(const int)(points + )];
edge = new Edge[(const int)(limit + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end, int cap, int flow){
edge[++ce] = Edge(end, h[from], cap, flow);
h[from] = ce;
}
inline void addDoubleEdge(int from, int end, int cap){
addEdge(from, end, cap, );
addEdge(end, from, cap, cap);
}
Edge& operator [](int pos){
return edge[pos];
}
inline int reverse(int pos){ //反向边
return (pos & ) ? (pos + ) : (pos - );
}
inline void clear(){
delete[] edge;
delete h;
ce = ;
}
}MapManager; #define m_begin(g, i) (g).h[(i)]
#define m_end(g, i) (g).edge[(i)].end
#define m_next(g, i) (g).edge[(i)].next
#define m_cap(g, i) (g).edge[(i)].cap
#define m_flow(g, i) (g).edge[(i)].flow
///map template ends int n, m;
int t;
MapManager g; inline boolean init(){
if(!readInteger(n)) return false;
readInteger(m);
t = n + m + ;
g = MapManager(t + , (n + ) * (m + ) * );
for(int i = , a, b; i <= n; i++){
readInteger(a);
while(a--){
readInteger(b);
g.addDoubleEdge(i, b + n, );
}
}
for(int i = ; i <= n; i++)
g.addDoubleEdge(, i, );
for(int i = ; i <= m; i++)
g.addDoubleEdge(i + n, t, );
return true;
} boolean *visited;
int* divs;
queue<int> que; inline boolean getDivs(){
memset(visited, false, sizeof(boolean) * (t + ));
divs[] = ;
visited[] = true;
que.push();
while(!que.empty()){
int e = que.front();
que.pop();
for(int i = m_begin(g, e); i != ; i = g[i].next){
int& eu = g[i].end;
if(!visited[eu] && g[i].flow < g[i].cap){
divs[eu] = divs[e] + ;
visited[eu] = true;
que.push(eu);
}
}
}
return visited[t];
} int blockedflow(int node, int minf){
if(node == t || minf == ) return minf;
int f, flow = ;
for(int i = m_begin(g, node); i != ; i = m_next(g, i)){
int& e = g[i].end;
if(divs[e] == divs[node] + && visited[e] && (f = blockedflow(e, min(minf, g[i].cap - g[i].flow))) > ){
flow += f;
g[i].flow += f;
g[g.reverse(i)].flow -= f;
minf -= f;
if(minf == ) return flow;
}
}
return flow;
} inline int maxflow(){
visited = new boolean[(const int)(t + )];
divs = new int[(const int)(t + )];
int res = ;
while(getDivs()){
res += blockedflow(, INF);
}
return res;
} inline void solve(){
int res = maxflow();
cout << res << endl;
} inline void clear(){
delete[] visited;
delete[] divs;
g.clear();
} int main(){
while(init()){
solve();
clear();
}
return ;
}

poj 1274 The Perfect Stal - 网络流的更多相关文章

  1. [题解]poj 1274 The Perfect Stall(网络流)

    二分匹配传送门[here] 原题传送门[here] 题意大概说一下,就是有N头牛和M个牛棚,每头牛愿意住在一些牛棚,求最大能够满足多少头牛的要求. 很明显就是一道裸裸的二分图最大匹配,但是为了练练网络 ...

  2. Luogu 1894 [USACO4.2]完美的牛栏The Perfect Stall / POJ 1274 The Perfect Stall(二分图最大匹配)

    Luogu 1894 [USACO4.2]完美的牛栏The Perfect Stall / POJ 1274 The Perfect Stall(二分图最大匹配) Description 农夫约翰上个 ...

  3. poj——1274 The Perfect Stall

    poj——1274   The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25709   A ...

  4. POJ 1274 The Perfect Stall || POJ 1469 COURSES(zoj 1140)二分图匹配

    两题二分图匹配的题: 1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求. 2.给你学生数和课程数,以及学生上的 ...

  5. POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24081   Accepted: 106 ...

  6. [POJ] 1274 The Perfect Stall(二分图最大匹配)

    题目地址:http://poj.org/problem?id=1274 把每个奶牛ci向它喜欢的畜栏vi连边建图.那么求最大安排数就变成求二分图最大匹配数. #include<cstdio> ...

  7. POJ 1274 The Perfect Stall (二分图匹配)

    [题目链接] http://poj.org/problem?id=1274 [题目大意] 给出一些奶牛和他们喜欢的草棚,一个草棚只能待一只奶牛, 问最多可以满足几头奶牛 [题解] 奶牛和喜欢的草棚连线 ...

  8. poj 1274 The Perfect Stall 解题报告

    题目链接:http://poj.org/problem?id=1274 题目意思:有 n 头牛,m个stall,每头牛有它钟爱的一些stall,也就是几头牛有可能会钟爱同一个stall,问牛与 sta ...

  9. POJ 1274 The Perfect Stall(二分图 && 匈牙利 && 最小点覆盖)

    嗯... 题目链接:http://poj.org/problem?id=1274 一道很经典的匈牙利算法的题目: 将每只奶牛看成二分图中左边的点,将牛圈看成二分图中右边的点,如果奶牛看上某个牛圈,就将 ...

随机推荐

  1. 牛客练习赛18E pocky游戏 状压dp

    正解:状压dp+辅助dp 解题报告: 来还债辣!NOIp之后还是轻松很多了呢,可以一点点儿落实之前欠下的各种东西一点点提升自己!加油鸭! 是个好题,可以积累套路,启发性强,而且很难 哦而且状压它也是个 ...

  2. 洛谷P1710 地铁涨价 图论

    其实是个傻逼题但是我太傻逼了然后就错了无数遍总算A了 觉得不写个题解真是亏了 其实是 之前想了个超时想法 然后还自以为很对?后来看了题解发现还是比较妙的哦 于是就想着那还是发个题解记录下趴quq 正解 ...

  3. ConcurrentLinkedQueue

    我们要实现一个线程安全的队列有两种实现方式,阻塞算法.非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁) 或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环 ...

  4. 迁移到 Linux:使用 sudo | Linux 中国

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/F8qG7f9YD02Pe/article/details/80976600 https://mmbi ...

  5. js与jQuery差别

    jQuery能大大简化Javascript程序的编写,我近期花时间了解了一下jQuery.把我上手过程中的笔记和大家分享出来.希望对大家有所帮助. 要使用jQuery.首先要在HTML代码最前面加上对 ...

  6. [js]ext.js探索

    Ext JS 经常会遇到布局等头疼的问题,一直在用bootstrap,但是我不喜欢这玩意出的效果想找个合适的js架构入手 http://examples.sencha.com/extjs/6.6.0/ ...

  7. hdu1864最大报销额(01背包)

    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=187#problem/G 该题要注意的就是每张单子A种类的总和不能大与600,同 ...

  8. [LeetCode] 257. Binary Tree Paths_ Easy tag: DFS

    Given a binary tree, return all root-to-leaf paths. Note: A leaf is a node with no children. Example ...

  9. [LeetCode] 152. Maximum Product Subarray_Medium tag: Dynamic Programming

    Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...

  10. numpy的prod()函数和pad()函数

    1.np.prod()函数用来计算所有元素的乘积,对于有多个维度的数组可以指定轴,如axis=1指定计算每一行的乘积. 2.np.lib.pad()函数用来把原来的list在原来的维度上进行扩展 例1 ...