1103: Party

Time Limit: 2 Sec  Memory Limit: 64 MB
Submit: 11  Solved: 7

Description

N students were invited to attend a party, every student has some friends, only if someone’s all friends attend this party, this one can attend the party(ofcourse if he/she has no friends, he/she also can attend it.), now i
give the friendship between these students, you need to tell me whether all of them can attend the party.
Note that the friendship is not mature, for instance, if a is b’s friend, but b is not necessary a’s friend. 

Input

Input starts with an integer T(1 <= T <= 10), denoting the number of test case.
For each test case, first line contains an integer N(1 <= N <= 100000), denoting the number of students.
Next n lines, each lines first contains an integer K, denoting the number of friends belong to student i(indexed from 1). Then following K integers, denoting the K friends.
You can assume that the number of friendship is no more than 100000, and the relation like student A is himself’s friend will not be existed. 

Output

For each test case, if all of the students can attend the party, print Yes, otherwise print No. 

Sample Input

2
3
1 2
1 3
1 1
3
1 2
0
1 1

Sample Output

No
Yes

HINT

For the first case:

Student 1 can attend party only if student 2 attend it.

Student 2 can attend party only if student 3 attend it.
Student 3 can attend party only if student 1 attend it.
So no one can attend the party. 

今天找了篇博客认真看了下拓扑排序,想自己重新写下这道题。一次就过了运气不错。(很多东西重新回过头来看会有更深入的理解和发现)仔细思考一下确实如文章所说:

不难看出该算法的实现十分直观,关键在于需要维护一个入度为0的顶点的集合:

每次从该集合中取出(没有特殊的取出规则,随机取出也行,使用队列/栈也行,下同)一个顶点,将该顶点放入保存结果的List中。

紧接着循环遍历由该顶点引出的所有边,从图中移除这条边,同时获取该边的另外一个顶点,如果该顶点的入度在减去本条边之后为0,那么也将这个顶点放到入度为0的集合中。然后继续从集合中取出一个顶点…………

当集合为空之后,检查图中是否还存在任何边,如果存在的话,说明图中至少存在一条环路。不存在的话则返回结果List,此List中的顺序就是对图进行拓扑排序的结果。

首先要知道一点入度和出度的概念,比如我在学数学之前要学语文,此时语文和数学之间有一个箭头,那按正常思维肯定是语文比数学优先吧,因为你肯定要先学语文才能学数学啊,那么就在语文和数学之间连一条有向边,就像这样语文——>数学,可以当成你玩游戏时的进度,过了语文这个任务才能过数学。嗯这样应该非常好理解了吧。

因此需要用到三个东西使得程序易于实现和理解

1、容器数组:是记录每一个顶点a所指向的顶点bi的集合;

比如1——>2那么我们就在vector[1]中压入2这个点。

2、入度数组:记录每一个顶点的入度。显然例子中rudu[数学]=1;

3、维护每次找到的入度为0的队列:拓扑排序可以看成一种模拟——首先找到入度为0的即没人可以制约它的点,然后将这个点和它指出去的边删去,此时它连到的点入度肯定会因此减1(平凡图情况下)。那么很可能此时又会产生一个/多个入度为0的点。然后又可以重复前面步骤了。直到找不到入度为0的点或者所有边已经访问过。

那拓扑归拓扑,排序是什么鬼?就是每次出现的入度变为0的点按照出现的先后顺序构成的一个序列。用容器或者数组加一个尾指针来保存就可以。当然此题不需要输出排序结果。

代码(注释内容可以输出排序结果):

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long LL;
int const N=100010;
int rudu[N];
vector<int>V[N];
inline void init(int n)
{
for (int i=0; i<=n; i++)
{
V[i].clear();
}
MM(rudu);
}
int main(void)
{
int tcase,i,j,a,n,m,sum;
scanf("%d",&tcase);
while (tcase--)
{
queue<int>Q;
scanf("%d",&n);
sum=0;init(n);
for (i=1; i<=n; i++)
{
scanf("%d",&m);
if(m==0)
{
Q.push(i);
continue;
}
for (j=1; j<=m; j++)
{
scanf("%d",&a);
V[a].push_back(i);
}
rudu[i]+=m;
sum+=m;
}
//vector<int>ans;
while (!Q.empty())
{
int now=Q.front();
Q.pop();
int sz=V[now].size();
for (i=0; i<sz; i++)
{
int v=V[now][i];
rudu[v]--;
sum--;
if(rudu[v]==0)
{
Q.push(v);
//ans.push_back(v);
}
}
}
if(sum)
puts("No");
else
{
puts("Yes");
/*for (vector<int>::iterator it=ans.begin(); it!=ans.end(); it++)
{
printf("%d ",*it);
}
putchar('\n');*/
}
}
return 0;
}

HUST——1103Party(拓扑排序+个人见解)的更多相关文章

  1. HUST 1103 校赛 邻接表-拓扑排序

    Description N students were invited to attend a party, every student has some friends, only if someo ...

  2. UVA10305 拓扑排序

    网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=117863#problem/B 思路分析:裸的拓扑排序,注释在代码中. 代码: #i ...

  3. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  4. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

  5. 【BZOJ-2938】病毒 Trie图 + 拓扑排序

    2938: [Poi2000]病毒 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 609  Solved: 318[Submit][Status][Di ...

  6. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  7. 图——拓扑排序(uva10305)

    John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...

  8. Java排序算法——拓扑排序

    package graph; import java.util.LinkedList; import java.util.Queue; import thinkinjava.net.mindview. ...

  9. poj 3687(拓扑排序)

    http://poj.org/problem?id=3687 题意:有一些球他们都有各自的重量,而且每个球的重量都不相同,现在,要给这些球贴标签.如果这些球没有限定条件说是哪个比哪个轻的话,那么默认的 ...

随机推荐

  1. 后台登录验证(Tokens/JSON Web Tokens(JWT) 的认证机制)

    sessionid不支持跨域,浏览器也不能禁止cookie(禁止以后sessionid还有什么用) 单点登录问题,即时SessionID一样,也无法跨域获取到数据 占坑

  2. 【UML】协作图Collaboration diagram(交互图)(转)

    http://blog.csdn.net/sds15732622190/article/details/49402269 前言         学完UML时序图,就要看一下UML协作图,因为两张图是相 ...

  3. [opencv] applyColorMap

    applyColorMap 功能 转化为热力图,因为热力图我们看的变化更加细微,在很多地方都用到了热力图. 最近在看CAM,所以记一记这个函数. 感觉还是很有用的. 代码 >>> i ...

  4. mysql中的空值问题

    MySQL的查询如果需要用到空值的情况下,where后面的条件就需要注意了 MySQL中的表示空值的方法:is null 和 is not null 比如:select * from user whe ...

  5. NOIP2018 - 暑期博客整理

    暑假写的一些博客复习一遍.顺便再写一遍或者以现在的角度补充一点东西. 盛暑七月 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士 比较经典的基环外向树dp.可以借鉴的 ...

  6. 深入理解 hashcode 和 hash 算法

    深入理解 hashcode 和 hash 算法 2017年12月30日 23:06:07 阅读数:5197 标签: hashhashmaphashcode二进制 更多 个人分类: jdk-源码  ht ...

  7. Eclipse将java项目导出可执行的jar文件

    1.在java项目上右键,点击“Export”,会弹出一个选择导出的文件类型 版权声明:本文为博主原创文章,未经博主允许不得转载. 原文地址:https://www.cnblogs.com/poter ...

  8. 文件处理seek以及修改内容的两种方式

    f.seek(offset,whence)offset代表文件的指针的偏移量,单位是字节byteswhence代表参考物,有三个取值# 0:参照文件的开头# 1:参照当前文件指针所在位置# 2: 参照 ...

  9. destoon去除编辑器替换图片删除原图功能,删除信息删除相关图片功能

    去除这些功能会造成大量垃圾图片,但是客户存在大量复制内容,其中图片一样,为了防止客户替换其中一个图片或者删除信息 造成其他复制信息图片丢失 去除文章模型级联图片功能. 对应模块class.php se ...

  10. machine_desc

    每一个machine,都要定义一个自己的machine_desc结构,该结构定义了该machine的一些最基本的特性. struct machine_desc { unsigned int nr; / ...