题解 P3254 【圆桌问题】

违规用户名cVn1I&r!

2018-03-27 13:32:07

Solution

圆桌问题,虽然在网络流24题里,可是并不需要跑网络流,只要贪心即可。 本人蒟蒻不会证明,证明略。。。。 对于这个题,只需要开二个结构体,一个存桌子的容量和当前已用空间,一个存单位人的数量与去向。 利用自带的sort将单位大小与桌子容量大小由大到小排序,因为越大的单位需要越多的桌子。 ```cpp #include<bits/stdc++.h> using namespace std; struct node{ int size; int now; int pre;//结构体储存排序前的位置,方便最后输出 }ta[1000]; struct edge{ int cap; int go[5000]; int pre;//结构体储存排序前的位置,方便最后输出 }uni[300]; bool cmp1(node a,node b) { return a.size>b.size; } bool cmp2(edge a,edge b) { return a.cap>b.cap;//由大到小排大小,容量 } bool cmp3(edge a,edge b) { return a.pre<b.pre; } int n,m; int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>uni[i].cap; uni[i].pre=i;//记录位置 } for(int i=1;i<=m;i++) { cin>>ta[i].size; ta[i].pre=i;//记录位置 } int k=1; sort(uni+1,uni+n+1,cmp2); sort(ta+1,ta+1+m,cmp1);//排序 for(int i=1;i<=n;i++)//循环单位 { int l=0;//当前单位可以满足的人数 for(int j=1;l<uni[i].cap&&j<=m;j++) { if(ta[j].now==ta[j].size) continue;//桌子满了就往后找有空的 uni[i].go[++l]=j;ta[j].now++;//记录去向,当前桌子坐的人数++ } if(l<uni[i].cap)//如果无法满足单位,退出 { cout<<0;return 0; } } sort(uni+1,uni+n+1,cmp3);//以原先顺序排单位,方便输出 cout<<1<<endl; for(int i=1;i<=n;i++) { for(int j=1;j<=uni[i].cap;j++) //从1-n输出单位去向 cout<<ta[uni[i].go[j]].pre<<" ";//输出桌子原先位置 cout<<endl; } } ```