bzoj 1124 [POI2008]枪战Maf 贪心
[POI2008]枪战Maf
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 741 Solved: 295
[Submit][Status][Discuss]
Description
有n个人,每个人手里有一把手枪。一开始所有人都选定一个人瞄准(有可能瞄准自己)。然后他们按某个顺序开枪,且任意时刻只有一个人开枪。因此,对于不同的开枪顺序,最后死的人也不同。
Input
输入n人数<1000000 每个人的aim
Output
你要求最后死亡数目的最小和最大可能
Sample Input
8
2 3 2 2 6 7 8 5
2 3 2 2 6 7 8 5
Sample Output
3 5
HINT
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 #define N 1000100 7 using namespace std; 8 int n,cnt; 9 int a[N]; 10 int du[N]; 11 int head[N]; 12 int vis[N]; 13 int v[N]; 14 int fir[N]; 15 struct node 16 { 17 int from,to,next; 18 }edge[N<<1]; 19 int belong[N]; 20 int cnt_du[N]; 21 int siz[N]; 22 int tot; 23 void init() 24 { 25 memset(head,-1,sizeof(head)); 26 cnt=1; 27 } 28 void edgeadd(int from,int to) 29 { 30 edge[cnt].from=from,edge[cnt].to=to,edge[cnt].next=head[from]; 31 head[from]=cnt++; 32 } 33 void dfs(int now,int ff) 34 { 35 vis[now]=1,belong[now]=tot,siz[tot]++; 36 for(int i=head[now];i!=-1;i=edge[i].next) 37 { 38 int to=edge[i].to; 39 if(to==now||to==ff||vis[to])continue; 40 dfs(to,now); 41 } 42 } 43 int check(int now,int num) 44 { 45 v[now]=1; 46 int t=now,cntt=1; 47 while(!v[a[t]]) 48 { 49 v[a[t]]=1; 50 t=a[t]; 51 cntt++; 52 } 53 t=a[t]; 54 if(t==now&&cntt==num)return 1; 55 return 0; 56 } 57 int main() 58 { 59 init(); 60 scanf("%d",&n); 61 for(int i=1;i<=n;i++) 62 { 63 scanf("%d",&a[i]); 64 du[a[i]]++; 65 edgeadd(i,a[i]); 66 edgeadd(a[i],i); 67 } 68 for(int i=1;i<=n;i++) 69 { 70 if(!vis[i]) 71 tot++,dfs(i,0),fir[tot]=i; 72 } 73 for(int i=1;i<=n;i++) 74 { 75 if(du[i]==0)cnt_du[belong[i]]++; 76 } 77 int ansma=0,ansmi=0; 78 for(int i=1;i<=tot;i++) 79 { 80 if(siz[i]==1)ansma++; 81 if(check(fir[i],siz[i])) 82 ansma+=siz[i]-1; 83 else ansma+=siz[i]-cnt_du[i]; 84 } 85 memset(v,0,sizeof(v)); 86 memset(vis,0,sizeof(vis)); 87 queue<int>q; 88 for(int i=1;i<=n;i++) 89 { 90 if(!du[i]) 91 q.push(i); 92 } 93 while(!q.empty()) 94 { 95 int u=q.front(); 96 q.pop(); 97 v[u]=1; 98 if(!vis[a[u]]) 99 { 100 v[a[u]]=vis[a[u]]=1,ansmi++; 101 du[a[a[u]]]--; 102 if(!du[a[a[u]]]) 103 q.push(a[a[u]]); 104 } 105 } 106 for(int i=1;i<=n;i++) 107 { 108 if(!v[i]) 109 { 110 int t=i,cnt=0; 111 while(!v[t]) 112 { 113 v[t]=1; 114 cnt++; 115 t=a[t]; 116 } 117 ansmi+=(cnt+1)/2; 118 } 119 } 120 printf("%d %d\n",ansmi,ansma); 121 }