BZOJ 1124 [POI2008]枪战Maf 贪心+乱搞
来源:互联网 发布:成捷迅概预算软件 编辑:程序博客网 时间:2024/04/27 18:49
题意:略。
方法:贪心+乱搞。
解析:
今天做的题里面最难的了…
分连通块进行考虑。
一个连通块最多死多少呢?
一个点 -> 死一个
一个环 -> 死环上点个数-1个
一个环加上内向树 -> 死所有点个数-入度为0个。
这很显然。。一棵树嘛..倒着开枪..
最少死多少个呢?
首先入度为零的肯定死不了。
然后我们将入度为0的推入队列。
之后他打死一个人后看那个人要打的人是否变成了入度为零。
如果变成了入度为零那么继续进队。
最后整张图剩下了一堆环。
环的结论很显然,明显是个数/2。
所以答案就出来啦.
代码:
#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 1000100using namespace std;int n,cnt;int a[N];int du[N];int head[N];int vis[N];int v[N];int fir[N];struct node{ int from,to,next;}edge[N<<1];int belong[N];int cnt_du[N];int siz[N];int tot;void init(){ memset(head,-1,sizeof(head)); cnt=1;}void edgeadd(int from,int to){ edge[cnt].from=from,edge[cnt].to=to,edge[cnt].next=head[from]; head[from]=cnt++;}void dfs(int now,int ff){ vis[now]=1,belong[now]=tot,siz[tot]++; for(int i=head[now];i!=-1;i=edge[i].next) { int to=edge[i].to; if(to==now||to==ff||vis[to])continue; dfs(to,now); }}int check(int now,int num){ v[now]=1; int t=now,cntt=1; while(!v[a[t]]) { v[a[t]]=1; t=a[t]; cntt++; } t=a[t]; if(t==now&&cntt==num)return 1; return 0;}int main(){ init(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); du[a[i]]++; edgeadd(i,a[i]); edgeadd(a[i],i); } for(int i=1;i<=n;i++) { if(!vis[i]) tot++,dfs(i,0),fir[tot]=i; } for(int i=1;i<=n;i++) { if(du[i]==0)cnt_du[belong[i]]++; } int ansma=0,ansmi=0; for(int i=1;i<=tot;i++) { if(siz[i]==1)ansma++; if(check(fir[i],siz[i])) ansma+=siz[i]-1; else ansma+=siz[i]-cnt_du[i]; } memset(v,0,sizeof(v)); memset(vis,0,sizeof(vis)); queue<int>q; for(int i=1;i<=n;i++) { if(!du[i]) q.push(i); } while(!q.empty()) { int u=q.front(); q.pop(); v[u]=1; if(!vis[a[u]]) { v[a[u]]=vis[a[u]]=1,ansmi++; du[a[a[u]]]--; if(!du[a[a[u]]]) q.push(a[a[u]]); } } for(int i=1;i<=n;i++) { if(!v[i]) { int t=i,cnt=0; while(!v[t]) { v[t]=1; cnt++; t=a[t]; } ansmi+=(cnt+1)/2; } } printf("%d %d\n",ansmi,ansma);}
0 0
- BZOJ 1124 [POI2008]枪战Maf 贪心+乱搞
- BZOJ 1124: [POI2008]枪战Maf 贪心 乱搞
- BZOJ 1124 [POI2008] 枪战Maf 乱搞。。
- BZOJ 1124 POI2008 枪战Maf 贪心
- bzoj 1124: [POI2008]枪战Maf(贪心)
- bzoj 1124: [POI2008]枪战Maf
- 1124: [POI2008]枪战Maf
- 1124: [POI2008]枪战Maf
- BZOJ1124: [POI2008]枪战Maf
- [POI2008]枪战Maf
- BZOJ1124: [POI2008]枪战Maf
- tarjin+暴力 [POI2008]枪战Maf
- 【BZOJ】【P1121】【POI2008】【激光发射器SZK】【题解】【乱搞】
- BZOJ 3799 字符串重组 贪心模拟乱搞
- BZOJ 1132: [POI2008]Tro
- bzoj 1131: [POI2008]Sta
- 【BZOJ 1116】 [POI2008]CLO
- BZOJ 1116: [POI2008]CLO
- 修改ubuntu终端里面那个提示符
- Oracle数据库安装成功后,忘记解锁账户和设置密码
- noip2006 明明的随机数 (模拟)
- 辛星收集整理之twig的常见用法
- Target-Action
- BZOJ 1124 [POI2008]枪战Maf 贪心+乱搞
- 产生死锁的原因
- android HttpClient的使用
- ZIP压缩算法详细分析及解压实例解释
- _net平台性能很不错的轻型ORM类Dapper
- MySql中创建存储过程
- hdu 2594 扩展KMP模板题
- noip2006 开心的金明 (01背包)
- 分层遍历时加NULL标记注意事项