http://acm.hdu.edu.cn/showproblem.php?pid=5098

软件在安装之后需要重启才能发挥作用,现在给你一堆软件(有的需要重启有的不需要)以及安装这个软件之前需要哪些软件发挥作用,求最少的重启次数

可以看出是拓扑排序,但是需要用两个队列q1,q2分别来存 不需要重启的software 和 需要重启的software。根据题目输入建好图后,按照拓扑序规则,首先将入度的0的点加进队列,不需要重启的进q1,需要的进q2。然后处理q1中的所有节点(即要删除这些点),那么要让与他们相连的节点的入度减1,如果发现减完入度为0,再判断其是否需要重启,并加进q1 or q2。一旦发现q1为空,那么使答案加1(不能继续任何安装即重启一次),把q2中所有元素加入q1,q2清空。如此循环直到q1,q2均为空即可。

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
const int maxn = 1050;
map <string , int> mp;
int ecnt,cnt;
int reboot[maxn],out[maxn],in[maxn];
struct edge{
int v,next;
}e[maxn*maxn];
int head[maxn],vis[maxn];
void init()
{
mp.clear();
ecnt = cnt = 0;
clr0(in),clr0(out),clr0(reboot);
clr1(head),clr0(vis);
}
void add(int u,int v)
{
e[ecnt].next = head[u];
e[ecnt].v = v;
head[u] = ecnt++;
}
int topo(){
queue<int> q1,q2;// 不需要重启的进q1,需要的进q2
for(int i = 1;i <= cnt;++i)if(in[i] == 0){
if(reboot[i] == 0)
q1.push(i);
else
q2.push(i);
}
int ans = 0;
while(!q1.empty() || !q2.empty()){
if(q1.empty() && !q2.empty()){
ans++;
while(!q2.empty()){
q1.push(q2.front());
q2.pop();
}
}
while(!q1.empty()){
int u = q1.front();q1.pop();
vis[u] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v;
in[v]--;
if(in[v] == 0){
if(reboot[v] == 0)
q1.push(v);
else
q2.push(v);
}
}
}
}
return ans;
}
int main()
{
string s;
char name[1050];
int _,cas = 1;RD(_);getchar();getchar();
while(_--)
{
init();
while(getline(cin,s)){
if(s[0] == '\0')
break;
istringstream sin(s);
sin >> name;
int len = strlen(name),flag = 0;
if(name[len - 2] == '*'){
flag = 1;
name[len - 2] = '\0';
}else
name[len - 1] = '\0';
string id = name,_id;
if(mp.find(id) == mp.end())
mp[id] = ++cnt;
reboot[mp[id]] = flag;
while(sin >> _id){
if(mp.find(_id) == mp.end())
mp[_id] = ++cnt;
add(mp[_id],mp[id]);
out[mp[_id]]++;
in[mp[id]]++;
}
}
printf("Case %d: %d\n",cas++,topo());
}
}

hdu 5098 双队列拓扑排序的更多相关文章

  1. ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TSH OJ-旅行商TSP)

    做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(T ...

  2. 题解报告:hdu 2647 Reward(拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 Problem Description Dandelion's uncle is a boss ...

  3. HDU 5811 Colosseo(拓扑排序+单调DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5811 [题目大意] 给出 一张单向图,现在将其划分成了两个部分,问划分之后的点是否分别满足按照一定 ...

  4. HDU 4857 (反向拓扑排序 + 优先队列)

    题意:有N个人,M个优先级a,b表示a优先于b.而且每一个人有个编号的优先级.输出顺序. 思路来自:与PKU3687一样 在主要的拓扑排序的基础上又添加了一个要求:编号最小的节点要尽量排在前面:在满足 ...

  5. HDU 2647 Reward(拓扑排序+判断环+分层)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 题目大意:要给n个人发工资,告诉你m个关系,给出m行每行a b,表示b的工资小于a的工资,最低工 ...

  6. HDU 4857 逃生 【拓扑排序+反向建图+优先队列】

    逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  7. hdu 1811(缩点+拓扑排序+并查集)

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. HDU 4857 逃生(拓扑排序)

    拓扑排序 一.定义 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈ ...

  9. hdu 3231 Box Relations (拓扑排序)

    Box Relations Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

随机推荐

  1. problem

    有两个数组a,b,大小都为n,数组元素的值任意,无序: 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小

  2. python socket和socketserver

    Python提供了两个基本的socket模块.一个是socket,它提供了标准的BSD Socket API:另一个是socketServer,它提供了服务器中心类,可以简化网络服务器的开发. 下面先 ...

  3. Thinkphp源码分析系列–开篇

    目前国内比较流行的php框架由thinkphp,yii,Zend Framework,CodeIgniter等.一直觉得自己在php方面还是一个小学生,只会用别人的框架,自己也没有写过,当然不是自己不 ...

  4. ASP.NET 操作Cookie详解 增加,修改,删除

    ASP.NET 操作Cookie详解 增加,修改,删除 Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密).定义于RFC2109.它 ...

  5. TStringList TMemo Text与Add赋值的区别 Memo.Text赋值高度注意事项,不得不知的技巧。

    Memo.Text赋值高度注意事项,不得不知的技巧. list := TStringList.Create;  list.Text:= str:  list.Count; list.Clear;  l ...

  6. Windows程序设计(第五版)学习:第四章 文本输出

    第四章 文本输出 1,客户区:整个应用程序窗口中没有被标题栏.边框.菜单栏.工具栏.状态栏和滚动条占用的区域.简而言之,客户区就是窗口中程序可以在上面绘制并向用户传达可视化信息的区域.   2,大多数 ...

  7. MFC坐标空间与映射模式

    逻辑坐标:使用GDI绘图时使用的坐标系 设备坐标系:实际设备(显示器.打印机)的坐标系,即我们实际看到的坐标系. 坐标空间 在Windows NT/2000中Win32 API中支持以下四层坐标空间: ...

  8. SHELL脚本攻略(学习笔记)--2.4 find

    转载请注明出处:http://www.cnblogs.com/f-ck-need-u/p/5916657.html   超级强大的find命令. find搜索是从磁盘搜索,而不是从数据库搜索. 2.4 ...

  9. DHCP服务器的开始方式

    方法一:采用DHCP服务器接口开启的方式 [Huawei]dhcp enable [Huawei]int g0/0/0[Huawei-GigabitEthernet0/0/0]ip add 192.1 ...

  10. TinyXML:一个优秀的C++ XML解析器

    //-------------------------------------------------------------------------------------------------- ...