您的位置:首页 > 其它

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

; 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); }

[p] 

 

二、强行拓扑贪心

  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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: