ural 1742. Team building
2015-08-27 22:29
513 查看
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1742
题意描述:一家公司,每个程序员都有自己唯一崇拜的大神(next);公司主管想用一个算法将这些程序员分成若干项目组,算法描述如下:
1.从剩下未分配的程序员中随机选出一个,标记为current程序员;
2.新建一个项目,将current分配进该项目;
3.若current有崇拜的大神,并且那个大神还没被分配,将大神分配进current所属项目组,并将大神变为current,重复3;否则回到1;
求按照这个算法所需的项目组数量的最大值和最小值;
思路大致是:入度为0的遍历 + 完全独立环的个数 = min; 节点数n - 形成环的节点个数 + 环数 = max;
代码中有几点细节需要说明:
1.step表示遍历节点的顺序,可在遍历判断出环时(遇到本轮遍历过的节点即可判断是环)用当前step-节点中的step得到环长度;
2.circle变量用于储存是在哪轮遍历中首次被遍历的点,用于对1的思路剪枝;
3.代码分成两个过程:遍历入度为0的点顺便找一下其中的环,遍历独立环;
AC代码:
题意描述:一家公司,每个程序员都有自己唯一崇拜的大神(next);公司主管想用一个算法将这些程序员分成若干项目组,算法描述如下:
1.从剩下未分配的程序员中随机选出一个,标记为current程序员;
2.新建一个项目,将current分配进该项目;
3.若current有崇拜的大神,并且那个大神还没被分配,将大神分配进current所属项目组,并将大神变为current,重复3;否则回到1;
求按照这个算法所需的项目组数量的最大值和最小值;
思路大致是:入度为0的遍历 + 完全独立环的个数 = min; 节点数n - 形成环的节点个数 + 环数 = max;
代码中有几点细节需要说明:
1.step表示遍历节点的顺序,可在遍历判断出环时(遇到本轮遍历过的节点即可判断是环)用当前step-节点中的step得到环长度;
2.circle变量用于储存是在哪轮遍历中首次被遍历的点,用于对1的思路剪枝;
3.代码分成两个过程:遍历入度为0的点顺便找一下其中的环,遍历独立环;
AC代码:
//#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdio.h> #include <vector> #include <queue> using namespace std; struct Node{ bool visit; int in, next, step, circle; Node() :circle(-1), visit(false), in(0), next(-1){} }; void func(){ int n, single, bCircle, cCircle, cnt, step; scanf("%d", &n); vector<Node>v(n + 1); for (int i = 1; i <= n; i++){ scanf("%d", &v[i].next); v[v[i].next].in++; } single = bCircle = cCircle = cnt = step = 0; for (int i = 1; i <= n; i++){ if (v[i].in == 0 && v[i].visit == false){ single++; int src = i; while (true){ v[src].step = step++; v[src].visit = true; v[src].circle = i; src = v[src].next; if (src == -1)break; v[src].in--; if (v[src].visit == false)continue; else if (v[src].circle == i){ cnt += step - v[src].step; bCircle++; } break; } } } for (int i = 1; i <= n; i++){ if (v[i].visit == false){ int src = i; cCircle++; while (true){ v[src].visit = true; v[src].step = step++; src = v[src].next; if (v[src].visit){ cnt += step - v[src].step; break; } } } } printf("%d %d\n", single + cCircle, n - cnt + bCircle + cCircle); } int main(){ //freopen("out.txt", "w", stdout); //freopen("in.txt", "r", stdin); func(); }
相关文章推荐
- iOS中的UIView的基本属性1
- iOS中的UILabel
- UISegmentedControl
- iOS中的按钮(UIButton)
- iOS中的文本框(UITextField)
- 国内UED收录
- iOS中的UIView的基本属性
- iOS中的屏幕的旋转(UIViewController)横屏竖屏
- iPhone开发之UIScrollView滚动组件的使用(二) 拖线实现按钮控制大图移动利用contentOffset属性
- 玩转UITableView
- iOS:转载:UIControl的使用
- iOS中的分段控件(UISegmentedControl)和滑块控件(UISlider)
- UILabel 详解
- 【APUE】Chapter11 Threads
- UI_10 表视图的编辑、UITableViewController
- 在QT Creator中简单的使用UI文件来设计界面并在源码中使用ui文件
- UI基础----常见控件的使用之TextView
- Qt学习(1):ui设计给窗口做背景及控件背景添加方法
- iPhone开发之UIScrollView滚动组件的使用——纯代码实现图形的横向与纵向滚动
- iOS中的导航条UINavigationController(UISegmentedControl)的基本使用(界面中传值的3中方法,单例,属性,代理)