[洛谷P3254] [網絡流24題] 圓桌遊戲
阿新 • • 發佈:2018-02-21
i++ out n) esp d+ truct 方案 scanf space
Description
假設有來自m 個不同單位的代表參加一次國際會議。每個單位的代表數分別為ri (i =1,2,……,m)。
會議餐廳共有n 張餐桌,每張餐桌可容納ci (i =1,2,……,n)個代表就餐。
為了使代表們充分交流,希望從同一個單位來的代表不在同一個餐桌就餐。試設計一個算法,給出滿足要求的代表就餐方案。
對於給定的代表數和餐桌數以及餐桌容量,編程計算滿足要求的代表就餐方案。
Input
第1 行有2 個正整數m 和n,m 表示單位數,n 表示餐桌數,1<=m<=150, 1<=n<=270。
第2 行有m 個正整數,分別表示每個單位的代表數。
第3 行有n 個正整數,分別表示每個餐桌的容量。
Output
如果問題有解,第1 行輸出1,否則輸出0。接下來的m 行給出每個單位代表的就餐桌號。如果有多個滿足要求的方案,只要輸出1 個方案。
Sample Input
4 5
4 5 3 5
3 5 2 6 4
Sample Output
1
1 2 4 5
1 2 3 4 5
2 4 5
1 2 3 4 5
想法
因為是網絡流24題,所以上來我先想的是怎麽用可愛的最小割。
沒想出來,於是仔細分析了一下題意。
發現,誒,好像貪心就可以啊……
單位代表數排個序,每個餐桌剩余容量排個序,先做剩余容量多的餐桌。
就A了……
之後又想了想網絡流怎麽做。
S向每個單位連容量為單位代表數的邊,每個單位向所有餐桌連容量為1的邊,每個餐桌向T連容量為餐桌容量的邊。
跑一邊最大流,看S發出的邊是否都滿流就完了。
這可真是一道辣雞題……
代碼
(貪心)
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int N = 275; const int M = 155; struct data{ int v,id; bool operator < (const data &b) const{ return v>b.v; } }d[N],r[M]; int c[M][N],w[M]; int n,m; int main() { scanf("%d%d",&m,&n); for(int i=1;i<=m;i++){ scanf("%d",&r[i].v); r[i].id=i; w[i]=r[i].v; } for(int i=1;i<=n;i++){ scanf("%d",&d[i].v); d[i].id=i; } int flag=1; sort(r+1,r+1+m); for(int i=1;i<=m;i++){ sort(d+1,d+1+n); for(int j=1;j<=r[i].v;j++){ if(!d[j].v) break; c[r[i].id][j]=d[j].id; d[j].v--; } if(!c[r[i].id][r[i].v]) { flag=0; break; } } if(flag==0) printf("0\n"); else { printf("1"); for(int i=1;i<=m;i++){ printf("\n%d",c[i][1]); for(int j=2;j<=w[i];j++) printf(" %d",c[i][j]); } } return 0; }
[洛谷P3254] [網絡流24題] 圓桌遊戲