POJ 3281 Dining 最大流 拆點

2022-07-23 17:33:15 字數 1888 閱讀 2547

解題思路:

令st=0為源點,en=f+2*n+1為匯點,

st向每種食物建流量為1的邊,

每種食物向喜歡它的牛(拆點1)建流量為1的邊,

眉頭牛的拆點之間建流量為1的邊,

每頭牛(拆點2)向它喜歡的飲料建流量為1的邊,

每種飲料向en建流量為一的邊。

注意,一定要將牛拆點,如果一頭牛只用乙個點然後連線飲料和食物,會導致一頭牛同時消耗多種食物和飲料。

這個自己畫圖模擬一下就能理解了。

**

1/*2

此題需要對奶牛進行拆點,左邊食物(水),中間奶牛1,奶牛2,右邊水(食物)

3拆點是為了限制奶牛只能吃乙份食物和誰,若不對奶牛進行拆點,則一頭奶牛可能會吃多份食物和水 4*/

5 #include6 #include7 #include8 #include9 #include10 #include11 #include12

#define ll long long

13#define pii pair14

#define pll pair15

#define rep(i,a,b) for(int i=a;i<=b;i++)

16#define per(i,a,b) for(int i=a;i>=b;i--)

17#define fast_io ios::sync_with_stdio(false);cin.tie(0);

18#define bug cout<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<19

#define bugc(_) cout << (#_) << " = " << (_) << endl;

20using

namespace

std;

21const

int n=1e6+5;22

const

int m=1e6+5;23

const

int inf=0x3f3f3f3f;24

25struct

nodeedge[m*2

];28

29int

cnt,st,en;

30int

head[n],dep[n];

3132

void

init()

3637

void link(int u,int v,int

flow);

39 head[u]=cnt++;

40 edge[cnt]=node;

41 head[v]=cnt++;42}

4344

intbfs()58}

59}60return

dep[en];61}

6263

int dfs(int u,int

fl)76}77

}78if(!tmp) dep[u]=-2;79

return

tmp;80}

8182

intdinic()88}

89return

ans;90}

9192

intmain()

105for(int j=1;j<=t2;j++)

110}

111for(int i=1;i<=f;i++) link(st,i,1

);112

for(int i=1;i<=n;i++) link(i+f,i+f+n,1

);113

for(int i=1;i<=d;i++) link(i+f+2*n,en,1

);114 printf("

%d\n

",dinic());

115}

116return0;

117 }

poj3281 dining 經典最大流建模方法

題意 有f中食物和d種飲料,每頭牛只能享用一種食物和飲料,每個食物跟飲料也只能被一頭牛享用。現在有n頭牛,每頭牛都有自己喜歡的食物種類列表和飲料列表,問最多能使幾頭牛同時享用到自己喜歡的食物和飲料。f,d,n都是一百以內的。思路 就不說一開始的想法了,是最近學習的最大流的建模裡面的新的方法。之前做過...

poj 3281 Dining(最大流基礎,拆點)

題意 思路 因為food和drink要麼同時要,要不都不要,則需要把它們串起來,牛放中間 對牛進行拆點以限制每頭牛吃了乙份food,和乙份drink const int inf int max 2 const int maxn 100000 const int maxv 500 struct edg...

Poj 3281 Dining 拆點網路流

題意和思路都和我部落格的這篇文章幾乎一樣 這裡有一組測試資料 include include include using namespace std const int inf 0x6fffffff 權值上限 const int maxpt 450 頂點數上限 const int maxeg 450...