日常训练 dfs 之 拓扑排序
今天被拓扑排序给折磨了一天,主要就是我的一个代码有点小bug,真难找。。。
先来看看我今天写的题目吧!
Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: "Fox"). She heard a rumor: the authors list on the paper is always sorted in the lexicographical order.
After checking some examples, she found out that sometimes it wasn't true. On some papers authors' names weren't sorted in lexicographical order in normal sense. But it was always true that after some modification of the order of letters in alphabet, the order of authors becomes lexicographical!
She wants to know, if there exists an order of letters in Latin alphabet such that the names on the paper she is submitting are following in the lexicographical order. If so, you should find out any such order.
Lexicographical order is defined in following way. When we compare s and t, first we find the leftmost position with differing characters: si ≠ ti. If there is no such position (i. e. s is a prefix of t or vice versa) the shortest string is less. Otherwise, we compare characters si and tiaccording to their order in alphabet.
The first line contains an integer n (1 ≤ n ≤ 100): number of names.
Each of the following n lines contain one string namei (1 ≤ |namei| ≤ 100), the i-th name. Each name contains only lowercase Latin letters. All names are different.
If there exists such order of letters that the given names are sorted lexicographically, output any such order as a permutation of characters 'a'–'z' (i. e. first output the first letter of the modified alphabet, then the second, and so on).
Otherwise output a single word "Impossible" (without quotes).
3
rivest
shamir
adleman
bcdefghijklmnopqrsatuvwxyz
10
tourist
petr
wjmzbmr
yeputons
vepifanov
scottwu
oooooooooooooooo
subscriber
rowdark
tankengineer
Impossible
10
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever
aghjlnopefikdmbcqrstuvwxyz
7
car
care
careful
carefully
becarefuldontforgetsomething
otherwiseyouwillbehacked
goodluck
acbdefhijklmnogpqrstuvwxyz
这个不是一个特别难的题目,就是一个比较经典的算法,拓扑排序。
然后我去学习了一下拓扑排序,学了入度表的,比较简单。
拓扑排序:大概就是你首先要建图,用vector或者链式前向星都可以,然后还要一个in数组,表示这个数的入度,
注意一下入度表示被指向的箭头数。然后就用一个for循环去找到入度为0的数,放入队列(如果有字典序的要求用优先队列就好了)
放入队列之后,再存下这个值,并且把这个指向的位置进行的入度减小,然后再判断一下被指向的数要不要放入队列。
queue<int>q;
for(int i=;i<n;i++) //n 节点的总数
if(in[i]==) q.push(i); //将入度为0的点入队列
vector<int>ans; //ans 为拓扑序列
while(!q.empty())
{
int p=q.top(); q.pop(); // 选一个入度为0的点,出队列
ans.push_back(p);
for(int i=;i<edge[p].size();i++)
{
int y=edge[p][i];
in[y]--;
if(in[y]==)
q.push(y);
}
}
if(ans.size()==n)
{
for(int i=;i<ans.size();i++)
printf( "%d ",ans[i] );
printf("\n");
}
else printf("No Answer!\n"); // ans 中的长度与n不相等,就说明无拓扑序列
这个题目就是一个拓扑的模板题,如果你会的话,应该比较容易想到,
首先我们对每个i和它之后的每一个字母进行枚举,之后的每一个字母一定要再第i个之后输出,
所以就可以用vector存图,然后再写一个tp的板子。应该就差不多这样,下面贴代码!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
vector<int>vec[110];
char s[110][110];
int vis[110][110];
int ou[110]; void tp()
{
priority_queue<int,vector<int>,greater<int>>que;
vector<int>ans;
for(int i=0;i<26;i++)
{
if (ou[i] == 0) que.push(i);
}
while(!que.empty())
{
int u = que.top(); que.pop();
int len = vec[u].size();
ans.push_back(u);
for(int i=0;i<len;i++)
{
int e = vec[u][i];
ou[e]--;
if (ou[e] == 0) que.push(e);
}
}
if (ans.size() < 26) printf("Impossible\n");
else
{
for (int i = 0; i <26; i++) printf("%c", ans[i]+'a');
printf("\n");
}
} int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++) scanf("%s", s[i]);
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
int len1 = strlen(s[i]);
int len2 = strlen(s[j]);
int p1 = 0, p2 = 0;
while (s[i][p1] == s[j][p2] && p1 < len1&&p2 < len2) p1++, p2++;
if(p1!=len1&&p2==len2)
{
printf("Impossible\n");
return 0;
}
if(p1!=len1&&p2!=len2)
{
int u = s[i][p1] - 'a', v = s[j][p2] - 'a';
if (vis[u][v]) continue;
vis[u][v] = 1;
vec[u].push_back(v);
ou[v]++;
}
}
}
tp();
return 0;
}
学完这个之后,我就马上写了两个很简单的板子题,从别人博客上找的,练练手。
确定比赛名次
Input输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3
1 2
2 3
4 3
Sample Output
1 2 4 3
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
vector<int>vec[550];
int in[550], n; void tp()
{
priority_queue<int, vector<int>, greater<int>>que;
vector<int>ans;
for (int i = 1; i <= n; i++) if (in[i] == 0) que.push(i);
while(!que.empty())
{
int u = que.top(); que.pop();
ans.push_back(u);
int len = vec[u].size();
for(int i=0;i<len;i++)
{
int v = vec[u][i];
in[v]--;
if (in[v] == 0) que.push(v);
}
}
int len = ans.size();
for (int i = 0; i < len-1; i++) printf("%d ", ans[i]);
printf("%d\n", ans[len - 1]);
} int main()
{
int m;
while(cin >> n >> m)
{
for (int i = 0; i <= n; i++) vec[i].clear();
memset(in, 0, sizeof(in));
for(int i=1;i<=m;i++)
{
int a, b;
cin >> a >> b;
vec[a].push_back(b);
in[b]++;
}
tp();
}
return 0;
}
Genealogical tree
And in the Planetary Council the confusing genealogical system leads to some embarrassment. There meet the worthiest of Martians, and therefore in order to offend nobody in all of the discussions it is used first to give the floor to the old Martians, than to the younger ones and only than to the most young childless assessors. However, the maintenance of this order really is not a trivial task. Not always Martian knows all of his parents (and there's nothing to tell about his grandparents!). But if by a mistake first speak a grandson and only than his young appearing great-grandfather, this is a real scandal.
Your task is to write a program, which would define once and for all, an order that would guarantee that every member of the Council takes the floor earlier than each of his descendants.
Input
Output
Sample Input
5
0
4 5 1 0
1 0
5 3 0
3 0
Sample Output
2 4 5 3 1 这个题目就是给你n个人,然后n行,第i行代表第i个人的后代,让你按照辈分从高到低的顺序输出。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
vector<int>vec[110];
int in[110], n;
void tp()
{
priority_queue<int, vector<int>, greater<int> >que;
vector<int>ans;
for (int i = 1; i <= n; i++) if (in[i] == 0) que.push(i);
while(!que.empty())
{
int u = que.top(); que.pop();
ans.push_back(u);
int len = vec[u].size();
for(int i=0;i<len;i++)
{
int v = vec[u][i];
in[v]--;
if (in[v] == 0) que.push(v);
}
}
int len = ans.size();
for (int i = 0; i < len-1; i++) printf("%d ", ans[i]);
printf("%d\n", ans[len - 1]);
} int main()
{
cin >> n;
for(int i=1;i<=n;i++)
{
int x;
while(cin>>x&&x)
{
in[x]++;
vec[i].push_back(x);
}
}
tp();
return 0;
}
日常训练 dfs 之 拓扑排序的更多相关文章
- 基于DFS的拓扑排序
传送门:Kahn算法拓扑排序 摘录一段维基百科上的伪码: L ← Empty list that will contain the sorted nodes S ← Set of all nodes ...
- HDU3342有向图判圈DFS&&拓扑排序法
HDU3342 Legal or Not 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 题目意思:一群大牛互相问问题,大牛有不会的,会被更厉害 ...
- 拓扑排序(基于dfs+基于队列)
经典问题-Ordering Tasks dfs函数的返回值表示是否成环,若存在有向环,则不存在拓扑排序.不包含有向环的有向图称为有向无环图(DAG) 可以借助DFS完成拓扑排序,在访问完一个结点时把他 ...
- 拓扑排序详解(梅开二度之dfs版按字典序输出拓扑路径+dfs版输出全部拓扑路径
什么是拓扑排序? 先穿袜子再穿鞋,先当孙子再当爷.这就是拓扑排序! 拓扑排序说白了其实不太算是一种排序算法,但又像是一种排序(我是不是说了个废话qwq) 他其实是一个有向无环图(DAG, Direct ...
- 有向无环图的应用—AOV网 和 拓扑排序
有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...
- 拓扑排序(topsort)
本文将从以下几个方面介绍拓扑排序: 拓扑排序的定义和前置条件 和离散数学中偏序/全序概念的联系 典型实现算法解的唯一性问题 Kahn算法 基于DFS的算法 实际例子 取材自以下材料: http://e ...
- 拓扑排序--UVa10305
题目 Output: standard output Time Limit: 1 second Memory Limit: 32 MB John has n tasks to do. Unfortun ...
- POJ1270 Following Orders (拓扑排序)
Following Orders Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4254 Accepted: 1709 ...
- UVA-10305 Ordering Tasks (拓扑排序)
题目大意:给出n个点,m条关系,按关系的从小到大排序. 题目分析:拓扑排序的模板题,套模板. kahn算法: 伪代码: Kahn算法: 摘一段维基百科上关于Kahn算法的伪码描述: L← Empty ...
随机推荐
- [PHP] 算法-将一个字符串转换成一个整数的PHP实现
题目描述 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一 ...
- jdk的配置(适用于win7、win8、win10)
一.前言 win7和win8的jdk配置基本一样,所以本文以win7和win10来说明配置. 二.win7jdk环境配置(win8和这个一样) 首先安装好jdk,这里已安装好jdk7,本文采取的是jd ...
- Python 字典(Dictionary) 基本操作
Python字典是一种可变容器模型,可存储任意类型对象:如字符串.数字.元组等.它以键值对(key-value)的形式存在,因此相当于Hashmap在python中的实现. §1. 创建字典 字典由 ...
- pullMsg有感
开发功能过程中,始终会有些东西是确认的,比如美丑.业务是否合理.对错. 如果明知道不合理,却按照已有规定.框架.设计去开发,其实是不够职业. 好的做法是朝对的方向去push,并落地: 次之是去push ...
- MySql: Year, Quarter, Month, Day, Hour statistics
-- 统计 select count(*) as '当天记录数' from web_product where date(p_createtime) = curdate(); select count ...
- SuperMap iClient for JavaScript image出图
SuperMap iClient for JavaScript 客户端基于openlayers 开发. 目前最高版本为811,9D产品后推荐客户使用leaflet.openlayers客户端开发. 问 ...
- JMeter java.net.SocketException:Operationnotsupported:connect解决方案
java.net.SocketException: Operation not supported: connect解决方案 by:授客 QQ:1033553122 测试环境 apache-jme ...
- 想让安卓app不再卡顿?看这篇文章就够了
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由likunhuang发表于云+社区专栏 实现背景 应用的使用流畅度,是衡量用户体验的重要标准之一.Android 由于机型配置和系统的 ...
- leetcode-58.最后一个单词的长度
leetcode-58.最后一个单词的长度 题意 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指由字母组成,但 ...
- .net、mono和C#
.net wiki:en chs .net版本 公共语言运行时(CLR) 发布时间 随同分发的Visual Studio 预装于windows系统 支持的windows系统 1.0 1.0 2002 ...