1. 程式人生 > >BZOJ1711 [Usaco2007 Open]Dining吃飯 題解&程式碼

BZOJ1711 [Usaco2007 Open]Dining吃飯 題解&程式碼

題意:
有N頭牛,F種食物和D種飲料,每頭牛有多種喜歡的食物和飲料,每頭牛隻可以吃一種食物和飲料,且每種食物和飲料都只能被一頭牛吃掉。一頭牛滿意當且僅當它吃到滿意的食物並且喝到想喝的飲料,問最多可能讓多少頭牛滿意。
題解:
把每頭牛拆成兩個點x和x+n,給x和x+n連一條容量為1的邊
如果一頭牛x喜歡一種食物,那麼給x和食物編號點連一條容量為1的邊
如果一頭牛x喜歡一種飲料,那麼給x+n和飲料編號點連一條容量為1的邊
食物編號點和點S之間分別連一條容量為1的邊
飲料編號點和點T之間分別連一條容量為1的邊
然後dinic就過啦!

對了我WA了好多次後來發現自己少讀了一個數據…madezz我是怎麼過樣例的

/**************************************************************
    Problem: 1711
    User: Rainbow6174
    Language: C++
    Result: Accepted
    Time:32 ms
    Memory:2496 kb
****************************************************************/

#include <cstdio>
#include<iostream>
#include <algorithm>
using namespace std; const int inf = 0x3f3f3f3f; int n,m,mf,md,head[1005],cur[1005],cnt,st,ed,deep[1005],q[10005]; struct edge{ int v,w,next; } e[100005]; void add(int u, int v, int w,int rw) { e[cnt]=(edge){v,w,head[u]}; head[u]=cnt++; e[cnt]=(edge){u,rw,head[v]}; head[v]=cnt++; } bool bfs(void
) { for(int i = st; i <= ed; i++) deep[i]=-1; int h=0,t=0; deep[st]=1; q[t++]=st; while(h != t) { int u = q[h++]; for(int i = head[u]; i!=-1; i = e[i].next) if(e[i].w && deep[e[i].v]==-1) { deep[e[i].v]=deep[u]+1; if(e[i].v==ed) return true; q[t++]=e[i].v; } } return false; } int dfs(int x,int flow) { if(x==ed)return flow; int left=flow; for(int i = cur[x]; i!=-1; i = e[i].next) if(e[i].w && deep[e[i].v]==deep[x]+1) { int tmp=dfs(e[i].v,min(left,e[i].w)); left-=tmp; e[i].w-=tmp; e[i^1].w+=tmp; if(e[i].w)cur[x]=i; if(!left)return flow; } if(left==flow)deep[x]=-1; return flow-left; } int dinic(void) { int ret=0; while(bfs()) { for(int i = st; i <= ed; i++) cur[i]=head[i]; ret+=dfs(st,inf); } return ret; } int main(void) { scanf("%d%d%d",&n,&mf,&md); st=0;ed=n*2+mf+md+1; for(int i = st; i <= ed; i++) head[i]=-1; for(int i = 1; i <= mf; i++) add(st,i+n*2,1,0); for(int i = n*2+mf+1; i < ed; i++) add(i,ed,1,0); for(int i = 1; i <= n; i++) add(i,i+n,1,0); int t1,t2,v; for(int i = 1; i <= n; i++) { //printf("%d\n",i); scanf("%d%d",&t1,&t2); //printf("%d %d\n",t1,t2); while(t1) { scanf("%d",&v); add(v+n*2,i,1,0); t1--; } while(t2) { scanf("%d",&v); add(i+n,v+n*2+mf,1,0); t2--; } } printf("%d\n",dinic()); return 0; }

相關推薦

BZOJ1711 [Usaco2007 Open]Dining吃飯 題解&程式碼

題意: 有N頭牛,F種食物和D種飲料,每頭牛有多種喜歡的食物和飲料,每頭牛隻可以吃一種食物和飲料,且每種食物和飲料都只能被一頭牛吃掉。一頭牛滿意當且僅當它吃到滿意的食物並且喝到想喝的飲料,問最多可能讓多少頭牛滿意。 題解: 把每頭牛拆成兩個點x和x+n,給

bzoj1711: [Usaco2007 Open]Dining吃飯

for ring int code typedef fine sizeof col lose 傳送門 水題啊,牛放食物飲料中間建邊即可,當然牛要拆點啊,我怎麽總是忘拆點啊。。 1 //Achen 2 #include<algorithm> 3 #

【BZOJ】1711: [Usaco2007 Open]Dining吃飯

play push scanf truct int urn ont rst 題解 【算法】最大流 【題解】 S連向食物連向牛連向牛‘連向飲料連向T。 經典的一個元素依賴於兩個元素的建圖方式。 #include<cstdio> #include<algo

bzoj 1711: [Usaco2007 Open]Dining吃飯

struct usaco std nbsp return memset fine fff color http://www.lydsy.com/JudgeOnline/problem.php?id=1711 源點連向食物流量為1,食物連向人流量為1,把人拆點限流,人

動態規劃 BZOJ1710 [Usaco2007 Open]Cheappal 廉價回文

nbsp 回文 ble time 每一個 bbs gre desc class 1710: [Usaco2007 Open]Cheappal 廉價回文 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 596 Solved: 3

bzoj1710【Usaco2007 Open】Cheappal 便宜回文

can pop stat 刪除 memory 一定的 rip pac 便宜 1710: [Usaco2007 Open]Cheappal 便宜回文 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 466 S

[Usaco2007 Open]Fliptile 翻格子遊戲

字典 esc and lin sds board side ant opened Description Farmer John knows that an intellectually satisfied cow is a happy cow who will give

[BZOJ1710][Usaco2007 Open]Cheappal 廉價回文

pro con stat col 分開 edi 回文 i++ problem 1710: [Usaco2007 Open]Cheappal 廉價回文 Time Limit: 5 Sec Memory Limit: 64 MB Submit: 645 Solved: 3

BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子遊戲:部分枚舉 位運算

define col turn com possible 最小 多少 格子 emc 題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 題意:   在一個n*m(1 <= n,m <= 15)的棋盤

【bzoj1710】[Usaco2007 Open]Cheappal 廉價回文

gpo for == ostream des 例如 iostream lib can 【bzoj1710】[Usaco2007 Open]Cheappal 廉價回文 Description 為了跟蹤所有的牛,農夫JOHN在農場上裝了一套自動系統. 他給了每一個頭

bzoj 1710: [Usaco2007 Open]Cheappal 廉價回文【區間dp】

枚舉 char cost print 對稱 return space amp clu 只要發現添加一個字符和刪除一個字符是等價的,就是挺裸的區間dp了 因為在當前位置加上一個字符x就相當於在他的對稱位置刪掉字符x,所以只要考慮刪除即可,刪除費用是添加和刪除取min 設f[i

bzoj 1645: [Usaco2007 Open]City Horizon 城市地平線【線段樹+hash】

ash 離散化 hash pan != 題目 getchar() cit names bzoj題面什麽鬼啊…… 題目大意:有一個初始值均為0的數列,n次操作,每次將數列(ai,bi-1)這個區間中的數與ci取max,問n次後元素和 離散化,然後建立線段樹,每次修改在區間上打

BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平線_掃描線

tro str n) mes NPU sample TP printf 向上 BZOJ_1654_[Usaco2007 Open]City Horizon 城市地平線_掃描線 Description N個矩形塊,交求面積並. Input * Line 1

bzoj 1647: [Usaco2007 Open]Fliptile 翻格子遊戲【dfs】

div 枚舉 del lag 高斯 possible true void 一個 這個可以用異或高斯消元,但是我不會呀我用的暴搜 2的m次方枚舉第一行的翻轉情況,然後後面的就定了,因為對於一個j位置,如果i-1的j位置需要翻,那麽一定要翻i的j,因為這是i-1的j最後翻的機會

$[ USACO 2007 OPEN ] Dining$

lol 需要 space get 麻煩 ctype != 得到 clas \(\\\) \(Description\) 有\(N\)頭牛,\(F\)種食物,\(D\)種飲料,每種食物和飲料只有一份。 現在已知每頭牛可以吃哪些食物,可以喝哪些飲料,問最多可以讓多少頭牛可以

BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子遊戲

str getchar() += put zoj ++ print cst ace 原理很簡單 只要確定第一行是否翻轉就可以確定以後的行是否翻轉 但是最後對拍後才過了 #include <cstdio> #include <cstring> #in

2018US Open Contest gold 題解

T1 題目大意:給定一個序列,求雞尾酒排序需要進行多少次原序列有序 n&lt;=106,ai&lt;=109n&lt;=10^6,a_i&lt;=10^9n<=106,ai​<=109 題解: 考察的是對氣泡排序以及

bzoj 1711 Dining吃飯 —— 最大流

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1711 食物一列,牛拆點,飲料一列。 程式碼如下: #include<cstdio> #include<cstring> #include<algorithm&g

【POJ2406】Power Strings 中文題意&題解&程式碼(C++)

Power Strings Time Limit: 3000MS Memory Limit: 65536K Description Given two strings a and b we define a*b to be their conca

HDU 1698 Just a Hook 題解&程式碼

題目要求是對於一個初始值均為1的區間進行區間修改,修改目標為:[a,b]區間內的值被修改為c 對於多組資料的每組資料輸出q次修改後的全區間和 基本線段樹了…只有兩個元素需要維護:sum和add,su