题目大意:
某个公司有n个程序员,每个程序员心中都认为自己是公司最好的程序员或者认为自己是第二好的
现在要将程序员们分成多个team,每次先选出一个当前没有被分组的程序员创立一个组,然后这个程序员认为最好的那个程序员如果没有加入任何组织的话,就将那个程序员加入这个组,同时在考虑新加入这个组的程序员认为最好的那个人,直到当前这个组里的程序员认为最好的人已经被分组。这个组就分配完毕,重新选择新的未分组的人创立新的组进行分配,直到所有人分配完毕。
现在给出所有的编号为i的程序员认为最好的程序员的编号 nex[i],问最多能分出多少组,最少能分出多少组
大致思路:
首先,这是一个有着n条有向边,n个顶点的图,要使得分的组数少的话,就是先每次选入度为零的点进行标记,然后沿着有向边一路标记下去,这样子可以有k1个组 ( k1 为入度是0的点的数量) 然后处理成环且环上的点都没有与其它入度为零的点有连接的情况,得到k2,那么 k1 + k2 即为答案
至于要最大分组,便是 总人数n - 形成环的人的个数 x + 环的个数y
代码如下:
Result : Accepted Memory : 1692 KB Time : 46 ms
/*
* Author: Gatevin
* Created Time: 2014/7/23 12:30:27
* File Name: test.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
int n;
int nex[100010];
int vis[100010];
int step[100010];
int notzero[100010];
int main()
{
while( scanf("%d",&n) == 1)
{
memset(notzero, 0, sizeof(notzero));
for(int i = 1; i <= n; i++)
{
scanf("%d",&nex[i]);
notzero[nex[i]] = 1;
}
memset(vis, 0, sizeof(vis));
memset(step, 0, sizeof(step));
int now = 1;
int cnt = 0;
int loop = 0;
int tmp;
for(int i = 1; i <= n; i++)
{
tmp = i;
if(vis[i] == 0)
{
vis[i] = now;
step[i] = 1;
while(!vis[nex[i]])
{
vis[nex[i]] = now;
step[nex[i]] = step[i] + 1;
i = nex[i];
}
if(vis[i] == vis[nex[i]])
{
cnt += (step[i] - step[nex[i]] + 1);
loop++;
}
}
now++;
i = tmp;
}
memset(vis, 0, sizeof(vis));
int answer = 0;
for(int i = 1; i <= n; i++)
{
tmp = i;
if(!notzero[i])
{
vis[i] = 1;
answer++;
while(!vis[nex[i]])
{
i = nex[i];
vis[i] = 1;
}
}
i = tmp;
}
for(int i = 1; i <= n; i++)
{
tmp = i;
if(!vis[i])
{
answer++;
vis[i] = 1;
while(!vis[nex[i]])
{
i = nex[i];
vis[i] = 1;
}
}
i = tmp;
}
printf("%d %d\n",answer, n - cnt + loop);
}
return 0;
}
/*
2
1 2
2 2
2
2 1
1 1
6
1 3 4 2 6 5
3 3
*/
/*
12
2 3 4 5 2 4 8 11 8 7 12 9
3 6
16
2
3
4
1
3
5
5
2
4
9
12
13
11
14
16
16
*/