bzoj3037 创世纪
2016-07-05 23:06
253 查看
两种解法:
一、树状DP
/*by SilverN*/ #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> using namespace std; const int INF=100000000; const int mxn=1002000; int hd[mxn],to[mxn],next[mxn]; int f[mxn],g[mxn],c[mxn]; int vis[mxn]; int cnt=0; int n,p,eg; void add_edge(int u,int v){ to[++cnt]=v;next[cnt]=hd[u];hd[u]=cnt; return; } void dfs(int now){ vis[now]=1; if(vis[c[now]]) p=now; else dfs(c[now]); return; } void solve(int now,int fa){ f[now]=1;g[now]=INF;vis[now]=1; if(now==eg){ g[now]=0; } int u=hd[now]; while(u!=0){ if(to[u]!=fa && to[u]!=p) { // printf("test msg4: now (%d) to (%d) \n",now,to[u]); solve(to[u],now); g[now]+=min(f[to[u]],g[to[u]]); g[now]=min(g[now],f[now]+f[to[u]]-1); f[now]+=min(f[to[u]],g[to[u]]); // printf("test msg5: f[now]: %d g[now]: %d \n",f[now],g[now]); } u=next[u]; } } int main(){ scanf("%d",&n); int i,j; for(i=1;i<=n;i++){ scanf("%d",&c[i]); add_edge(c[i],i);//反向存边 } int ans=0; for(i=1;i<=n;i++){ if(!vis[i]){ // printf("test msg1: dfs(%d)\n",i); dfs(i); // printf("test msg2: p(%d)\n",p); eg=c[p]; solve(p,0); int tmp=f[p]; // printf("test msg3: tmp(%d)\n",tmp); eg=0; solve(p,0); ans+=min(tmp,g[p]); } } printf("%d\n",n-ans); }
二、强行拓扑贪心
AC
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> using namespace std; const int INF=100000000; const int mxn=1002000; int in[mxn]; int ctl[mxn]; bool flag[mxn]; int n,cnt=0; int ans=0; int main(){ scanf("%d",&n); int i,j; for(i=1;i<=n;i++){ scanf("%d",&ctl[i]); in[ctl[i]]++;//统计入度 } queue<int>q; for(i=1;i<=n;i++){ if(!in[i]) q.push(i); } int tmp; while(!q.empty()){ tmp=q.front(); q.pop(); if(!flag[tmp] && !flag[ctl[tmp]]){ ans++; flag[ctl[tmp]]=1; in[ctl[ctl[tmp]]]--; if(!in[ctl[ctl[tmp]]]){//减后入度为0 q.push(ctl[ctl[tmp]]); } } flag[tmp]=1; } for(i=1;i<=n;i++){ if(!flag[i]){ cnt=1;j=i; flag[i]=1; while(ctl[j]!=i){ flag[ctl[j]]=1;//处理环 cnt++; j=ctl[j]; } ans+=cnt/2;//环上一半的点可以投放 } } printf("%d\n",ans); return 0; }
相关文章推荐
- Python网络编程—socket(一)
- netty httpserver
- Maven的安装、配置及使用入门
- Matlab的数据输出
- 移动端H5 QQ在线客服链接代码
- 最近面试 有人问 sqlite 用过么 sqlite 不是 嵌入式的 开发 么 难道最近还 web开发 了?
- C# webbrowser爬虫中经常碰到的脚本错误弹出窗口的问题解决
- 浅谈当前情况下的视频内容收费
- Android Studio 表格布局实现登录界面
- 本程序员要回家啦
- 游戏编程模式:前言(架构,性能和游戏)(Part III)
- leetcode: Word Break
- nodejs设计思想杂技二 callback 模式
- Android权限大全
- c3p0配置在spring配置文件中的详细配置
- Python 在Windows下安装matplotlib
- delphi query阻塞执行 长时间执行sql的解决办法
- VBS获取当前文件目录
- HDU 1312 Red and Black
- 排序算法之冒泡排序、选择排序、直接插入排序(java实现)