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<=106,ai<=109n<=10^6,a_i<=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