您的位置:首页 > 其它

【HDU】 3605 Escape(暴力做法...)

2016-05-16 14:32 267 查看

Escape

题目链接

Escape

题目大意

意思就是说现在世界末日要来了,地球上有n各人要跑到其他的星球上去,但是每个人只

能到若干星球上去,现在告诉你每个星球能容纳的人数,需要你判断是否所有的人都能

躲过世界末日。

题解

这道题首先看到人数很多,但是星球只有10个,所以我们考虑不同的人最多只有

210−12^{10}-1 个,这样我们就可以用位元算的方式解出每种人有多少个,然后开始建图。

建图

总共m+1个点,源点是m,汇点是m+1,我们遍历每一种人,从源点向他能去的点建立

一条长度为该种人人数的边,再从每一个星球向汇点建立一条长度为该星球能容纳人数

的边。

处理

我们发现建完这个图后,对于每个星球,有且仅有两条边与他相连,一个是从源点过来

的,一条是指向汇点的,所以我们现在只需要将这两条边取最小的然后加到ansans中就行

了(暴力)…

代码

最后取最大的时候是很快的,主要时间都在建图了(交了10次,平均时间在1700ms左右,有一次超时)…

能暴力为啥不暴力啊!!!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>

using namespace std;

int n,m,x,nump[1050],p[15],e[30];
int c[11]={1,2,4,8,16,32,64,128,256,512,1024};

int solve()
{
int ans=0;
for (int i=0;i<m;i++) ans+=min(e[i],e[i+m]);
return ans;
}

int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(p,0,sizeof(p));
memset(nump,0,sizeof(nump));
for (int i=1;i<=n;i++)
{
int sum=0;
for (int j=1;j<=m;j++)
{
scanf("%d",&x);
if (x) sum+=c[j-1];
}
nump[sum]++;
}
for (int i=0;i<m;i++) scanf("%d",&p[i]);
if (nump[0])
{
printf("NO\n");
continue;
}
//deal
memset(e,0,sizeof(e));
for (int i=1;i<=c[m];i++) if (nump[i])
for (int j=0;j<m;j++) if ((1<<j)&i) e[j]+=nump[i];
for (int i=0;i<m;i++) if (p[i]) e[i+m]+=p[i];
int ans=solve();
if (ans>=n) printf("YES\n");
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: