某帝国拥有着N 种被称作“世界之威”的新型武器。现在为了国家的经济发展,它需要很多资金,为此,此帝国总统OBM准备把一些武器卖给其它国家。
此帝国总统OBM知道,这N种武器之间可能会相互受限制的。例如,第3种武器会打败第1种武器,第4种武器会打败第3种武器等等。他希望所有被卖出的武器中都至少有一种限制它的武器在他手中,目的是此帝国能制约住其它国家,这样就可以保持对世界的霸权地位。
但总统OBM头脑有点笨,他想知道他最多可以卖出多少种武器,你愿意帮助他吗?
(你可以告诉电脑,但不告诉他喽。)
第一行: K 表示有多少组测试数据。
接下来对每组测试数据:
第1行: N 表示有多少种新型武器
第2~N+1行: A1 A2……AN 表示第i 种武器能限制住第Ai 种武器
1≤K≤10 0≤N≤106 1≤Ai≤N
对于每组测试数据,输出占一行:最多可以卖出的武器种类数
172 3 1 3 6 5 4
3
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <climits>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#define INF 100000000
using namespace std;
int a[100005],d[100005],vis[100005];
int main(){
int t;
cin >> t;
while(t --){
int n;
scanf("%d",&n);
priority_queue<int,vector<int>,greater<int> > que;
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
int ans = 0,num = 0;
for(int i = 1;i <= n;i++){
scanf("%d",&a[i]);
if(a[i] == i){
num++;
}
d[a[i]] ++;
}
for(int i = 1;i <= n;i++){
if(d[i] == 0){
que.push(i);
}
}
while(!que.empty()){
int p = que.top();
que.pop();
ans += 1;
vis[p] = 1;
if(vis[a[p]]){
num += 1;
continue;
}
d[a[a[p]]] --;
vis[a[p]] = 1;
if(d[a[a[p]]] == 0){
que.push(p);
}
num += 2;
}
ans += (n-num) / 2;
printf("%d\n",ans);
}
return 0;
}
原文地址:http://blog.csdn.net/qq_24667639/article/details/45278513