题解 P3254 【圆桌问题】

MelodyJiYang

2018-03-31 16:17:50

Solution

圆桌问题从题目标签上是网络流24题,但是想了一下,再A掉之后又看了一题解,发现和我一样写贪心的童鞋好像没有与我思路相同的,所以我就来写个第一篇题解吧。 思路大致如下: 1、 将数据按要求输入并存储下来。 2、 对于每一个单位的每一个而言,每次都只坐没有同事,并且空座最多的桌子(桌子容量依次减少)。 3、 将落座的人所坐的桌号用桶排序的方法记录下来。 4、 所有单位处理完成后,按次序输出结果。 代码奉上,自取不谢。 ```cpp #include<cstdio> #include<cstring> //引入必要的头文件 using namespace std; int danwei[200]; struct zhuo//创建一个用于存储桌子信息的结构体数组 { int shu; int wei; }t[300]; int m,n; int vis[300];//记录每张桌子上是否有本单位的人 int res[200][300];//答案数组 inline int dfs(int num,int i)//处理每个单位代表落座的函数 { if(num==0) return 1;//代表全都落座则返回 int rong=0; int index=0; for(int j=1;j<=n;j++)//循环以找到桌子剩余座位的最大值 { if(t[j].shu==t[j].wei || vis[j]) continue;//如果桌子坐满或者单位有人坐过就找下一张桌子 if(rong<(t[j].wei-t[j].shu))//如果容量比最大容量大则更新最大容量和它的位置 { rong=(t[j].wei-t[j].shu); index=j; } } if(index==0) return 0;//容量为空则说明无法坐下,题目不成立 vis[index]=1;//落座,改变桌子的容量 t[index].shu++; res[i][index]++;//记录答案,表示第i号单位的第index章桌子上有人 int r=dfs(num-1,i);//看本单位下一个人能否落座 return r; } inline void sc()//输出答案函数 { printf("1\n"); for(int i=1;i<=m;i++) { int j=1; int num=0; for(;j<=n;j++) { if(res[i][j]==0) continue;//如果桌子上没人,就看下一张桌子 printf("%d",j);//有人就打印桌子号 if(++num!=danwei[i])printf(" "); else printf("\n"); } } } inline int A()//伪主函数(提高效率使用,执行时从这里执行) { scanf("%d %d",&m,&n);//输入m和n for(int i=1;i<=m;i++)//输入每个单位的人数 { scanf("%d",&danwei[i]); } for(int i=1;i<=n;i++)//输入每张桌子的位置数 { scanf("%d",&t[i].wei); } for(int i=1;i<=m;i++)//循环对于每一个单位人数去找座位 { int r=dfs(danwei[i],i);//调用处理落座的函数 if(r==0)//有人无法落座则不符合题目要求 { printf("%d\n",r); return 0; } memset(vis,0,sizeof(vis));//对于每一次运行清空桌子的访问记录 } sc();//调用输出函数 return 0;//函数结尾 } int B=A();//调用伪主函数 int main()//真的毫无内容的主函数 { return 0; //函数结尾 } ```