網路流之P3254 圓桌問題

2022-05-03 14:09:23 字數 1926 閱讀 5797

假設有來自m 個不同單位的代表參加一次國際會議。每個單位的代表數分別為ri (i =1,2,……,m)。

會議餐廳共有n 張餐桌,每張餐桌可容納ci (i =1,2,……,n)個代表就餐。

為了使代表們充分交流,希望從同乙個單位來的代表不在同乙個餐桌就餐。試設計乙個演算法,給出滿足要求的代表就餐方案。

對於給定的代表數和餐桌數以及餐桌容量,程式設計計算滿足要求的代表就餐方案。

輸入格式:

第1 行有2 個正整數m 和n,m 表示單位數,n 表示餐桌數,1<=m<=150, 1<=n<=270。

第2 行有m 個正整數,分別表示每個單位的代表數。

第3 行有n 個正整數,分別表示每個餐桌的容量。

輸出格式:

如果問題有解,第1 行輸出1,否則輸出0。接下來的m 行給出每個單位代表的就餐桌號。如果有多個滿足要求的方案,只要輸出1 個方案。

輸入樣例#1: 複製

4 5

4 5 3 5

3 5 2 6 4

輸出樣例#1: 複製

1

1 2 4 5

1 2 3 4 5

2 4 5

1 2 3 4 5

圓桌問題

網路流,是乙個匹配問題。

可以把求乙個人員的分配,轉化成乙個網路流問題

轉化:這個題目是要求所有的人都可以合理的分配到每乙個桌子,這個所謂的合理就是乙個單位的不許坐在一起。

所以就建乙個圖,把每乙個單位都和所有的桌子連一條權值為1的線,意思是這個單位只能分配乙個人到這裡。

然後每乙個單位到源點連一根線這根線權值是這個單位的人,然後就是每乙個桌子連一根線到匯點,線的權值就是桌子能做的人。

這就是建圖,然後你會發現,如果我們要合理分配,那麼就是從源點到匯點的最大流為所有單位人之和。

也就是源點連的每一條線的邊權值。

建圖之後就是乙個dinic的板子。

然後就是乙個乙個路徑的輸出,這個路徑的輸出很簡單,就是判斷這條邊(就是單位到桌子)的負邊的權值是不是-1,

如果是,則說明這個單位有乙個人坐在這裡。

#include #include 

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

using

namespace

std;

const

int maxn = 1e5 + 10

;int

s, t, n, m;

struct

node

};vector

e;vector

g[maxn];

intlevel[maxn], iter[maxn], head[maxn];

void add(int u,int v,int

c)void bfs(int

s) }

}}int dfs(int u,int v,int

f) }

}return0;

}int sum = 0

;bool

dinic()

}vector

to[maxn];

intmain()

for(int i=1;i<=n;i++)

for(int i=1;i<=m;i++)

}int ans =dinic();

printf(

"%d\n

", ans);

if(ans)

for(int i=1;i<=m;i++)

printf("\n

");}

return0;

}

P3254 圓桌問題

假設有來自m 個不同單位的代表參加一次國際會議。每個單位的代表數分別為ri i 1 2,m r i i 1,2,m 會議餐廳共有n 張餐桌,每張餐桌可容納ci i 1 2,n c i i 1,2,n 個代表就餐。為了使代表們充分交流,希望從同乙個單位來的代表不在同乙個餐桌就餐。試設計乙個演算法,給出...

P3254 圓桌問題

網路流建模,同時求出最大流的乙個可行流 建模如下 求可行流的方法 遍歷左邊的所有節點,在殘留網路上跑滿了流的邊即為一組解 include using namespace std const int n 430,m n 150 270 2,inf 1e8 int n,m,s,t int h n e m...

P3254 圓桌問題

題目鏈結 非常簡單的一道網路流題 我們發現每個單位的人要坐到不同餐桌上,那也就是說每張餐桌上不能有同一單位的人。這樣的話,我們對於每個單位向每張餐桌連一條邊權為1的邊,表示同一餐桌不得有相同單位的人。從源點向每個單位連一條邊權為人數的邊,從餐桌向匯點連一條邊權為餐桌容量的邊,這樣的話跑最大流,跑出來...