拓扑排序

HDU 2647 Reward【反向拓扑排序】

一曲冷凌霜 提交于 2020-01-10 10:11:20
Reward Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11836 Accepted Submission(s): 3804 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. The workers will compare their rewards ,and some one may have demands of the distributing of rewards ,just like a's reward should more than b's.Dandelion's unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work's

HDU 2647 Reward 拓扑排序

天大地大妈咪最大 提交于 2020-01-10 10:11:04
http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意:   输入N和M代表N个人和M组数据,M组数据中的A和B代表A的工资要比B的工资高,底薪是(888元),问你这个老板至少要付 多少钱给这些员工,A比B工资高就是说A的工资“至少”比B高1元,当拓扑排序出现环的时候输出 -1 ,否则输出老板要给的钱数。 坑爹:   用拓扑排序找到入度为0的所有的点都有着同样的工资。 例如:1-2 3-4 这样1和3都为889元,2和4为888元,所以老板所付的总工资为3554元。 解法:   在每次调用cut函数的时候都要访问与他相邻的边的点的入度,每访问一次IN[ map[ k ][ i ] ] --;我们可以在每次判断一下当前的点(k) 的工资+1与map[ k ][ i ] 的工资的比较大小,取大的一个放入map[ k ][ i ] 的工资里,因为某个人可能在某条线路上工资排名可能是第二, 但在另一条线路上工资排名可能就是排第三了,根据题意,所以这个人的工资为890而不是889。 例如: 这样的话1和2为888,3为889,4为890,5为891。 View Code 1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 5 const int maxn = 10000

hdu2647Reward(拓扑排序)

亡梦爱人 提交于 2020-01-10 10:10:52
http://acm.hdu.edu.cn/showproblem.php?pid=2647 定义一个数组 来标记 保证每次循环找到的是同一层次的 它们加的数是相同的 用f来表示找到多少个入度为0的点 <n时 有环 输出-1 View Code 1 #include<stdio.h> 2 #include<string.h> 3 struct node 4 { 5 int v,w,next; 6 }men[20001]; 7 int first[10001],de[10001],t,kk[10001]; 8 void init() 9 { 10 t = 0; 11 memset(first,-1,sizeof(first)); 12 } 13 void add(int u,int v) 14 { 15 men[t].v = v; 16 men[t].next = first[u]; 17 first[u] = t; 18 t++; 19 } 20 void topo(int n) 21 { 22 int i,j,k,f = 0,o=0; 23 __int64 s = 0,w=888,g; 24 memset(kk,0,sizeof(kk)); 25 for(i = 1; i <= n ; i++) 26 { 27 for(j = 1 ; j <= n ;j++) 28 { 29

(拓扑排序)HDU - 2647 Reward

≯℡__Kan透↙ 提交于 2020-01-10 10:10:35
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意: 一场比赛,现在已经有了结果,主办方要给选手分配奖励,判断是否能够分配,如果不能就输出-1,不能的话就输出主办方最小需要准备的奖金总数。 每个选手最低给888元。 分析: 拓扑排序入门题吧。。 我选择邻接表。 把边倒着连,就能从最小开始,然后在进行队列的时候,然后进行一次拓扑排序即可,这里不同的奖金额度只需要用一个结构体里存一个level属性就可以了,一开始为0,后面push的+1就行了。 每次pop加888+level。 注意的地方就是:这题需要输出-1,一开始我只判断了有双向边,其实还应该判断是否成环,只要加个变量记录点访问的个数就行了。 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<set> 7 #include<vector> 8 #include<queue> 9 #include<map> 10 #include<list> 11 #include<bitset> 12 #include<string> 13 #include<cctype> 14 #include

[HDU] 2647 Reward(拓扑排序)

我怕爱的太早我们不能终老 提交于 2020-01-10 10:10:20
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=2647 拓扑排序问题,反向建图,则最后入度为0的点初始金钱为888,以后每次删边入度为0的点金钱比上次+1即可。若存在环,则不可能出现,输出-1。 1 #include<cstdio> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 #include<stdbool.h> 7 #include<time.h> 8 #include<stdlib.h> 9 #include<set> 10 #include<map> 11 #include<stack> 12 #include<queue> 13 #include<vector> 14 using namespace std; 15 #define clr(x,y) memset(x,y,sizeof(x)) 16 #define sqr(x) ((x)*(x)) 17 #define rep(i,a,b) for(int i=(a);i<=(b);i++) 18 #define LL long long 19 #define INF 0x3f3f3f3f 20 #define A first 21 #define

码农找工作之:秒杀算法面试必须掌握的14种模式

ぃ、小莉子 提交于 2020-01-07 20:38:40
对于茫茫多的程序员来说,准备算法面试简直就是一个亚历山大的过程。看不完的学习资料,更惨的是,很多内容和程序员干的事情感觉相去甚远,这无疑只会雪上加霜。 这样的结果之一就是:程序员需要花上数周的时间在诸如LeetCode这样的在线编程平台上准备刷上几百个面试题目。这些焦虑的程序员都关心类似的问题: 我刷了足够的题了吗?我应该再来点吗? 这就是为啥我专注于帮助码农们掌握每个问题背后的模式的原因:这样的话,你们就不需要苦逼哈哈地担心着茫茫多的(一千多道)LeetCode的进度条了,也帮助你们避免盲目刷题的疲劳。如果你理解这些通用的模式,你就可以把他们当做是模板,去解决其他类似的被改头换面过的题目了。 这篇文章就和大家唠唠所有的面试题目可能的14种模式。当然更重要的,我会给大家讲讲怎么去识别每种模式,每个模式再给大家来几个样题尝尝鲜。当然,这些只是冰山一角啦,详细的,不用多说,墙裂推荐你去看这门课: Grokking the Coding Interview: Patterns for Coding Questions 该课程提供详细的理论讲解,例子和编程训练。 如果你需要买该网址的任何课程,都可以使用coupon code: awesome-developer-20 拿到额外八折。 接下来的这些模式是建立在你已经知晓了数据结构的基础之上的。如果你还没掌握的话,嘿嘿,推荐你去看:

力扣207——课程表

风格不统一 提交于 2020-01-07 11:10:07
这道题主要利用拓扑排序,判断该图是否有环,其中还会涉及到邻接矩阵。 原题 现在你总共有 n 门课需要选,记为 0 到 n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1] 给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习? 示例 1: 输入: 2, [[1,0]] 输出: true 解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。 示例 2: 输入: 2, [[1,0],[0,1]] 输出: false 解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。 说明: 输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。 你可以假定输入的先决条件中没有重复的边。 提示: 这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。 通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。 拓扑排序也可以通过 BFS 完成。 原题url:https://my.openwrite.cn/user/article/write 解题

拓扑排序

谁说我不能喝 提交于 2019-12-27 07:20:09
拓扑排序 从离散数学的角度定义,假设(A,≤)是有限偏序集,对其进行拓扑排序是指将其扩展成一个全序集,使得≤∈<,即对任意的a,b∈A,若a≤b,则a<b。 从图论的角度定义,对一个有向无环图G进行拓扑排序,是将G中所有的顶点排成一个线性序列,使得图中任意一对顶点u和v,如果(u,v)∈E(G),则u在线性序列中应出现在v之前。 思路 从离散数学的角度定义,拓扑排序是针对有限偏序集的,由离散数学的知识知,若(A,≤)是偏序集,则拟序集(A,<)中不存在长度大于1的环(这其实与无环图对应),所以有限偏序集可以画成哈斯(Hasse)图。Hasse图非空时总存在极小元,每次输出极小元,更新Hasse图,直到Hasse为空。 从图论的角度,极小元等同于图中入度为0的顶点,每次输出入度为0的点,更新与之相连点的入度,直到输出全部顶点。如果存在顶点没有输出,说明存在环。 样题 给任务排序(UVa10305) 假设有n个任务,还有m个二元组(u,v),(u,v)表示u必须在v之前执行。请输出n个任务按顺序执行的一种可能情况。 代码实现 邻接矩阵+队列 1 #include<stdio.h> 2 #include<cstring> 3 #include<queue> 4 #include<vector> 5 using namespace std; 6 7 const int V = 100 +

拓扑排序

前提是你 提交于 2019-12-27 07:15:21
#include<cstdio> #include<queue> #include<cstring> #include<vector> using namespace std; const int maxm = 105; vector<int> ve[maxm]; int indeg[maxm], n, m, num, a[maxm], x, y; queue<int> q; void topsort() { while(!q.empty())q.pop(); num = 0; for(int i = 1; i <= n; i++) { if(!indeg[i]) q.push(i); } while(!q.empty()) { int nx = q.front(); a[num++] = nx; q.pop(); for(int i = 0; i < ve[nx].size(); i++) { if(--indeg[ ve[nx][i] ] == 0) q.push(ve[nx][i]); } } } //num小于n的话说明有环,因为环中的元素进不去队列。等于n说明没环 int main() { while(~scanf("%d%d", &n, &m)) { if(n == 0 && m == 0) break; memset(indeg, 0, sizeof(indeg));

数据结构—拓扑排序

杀马特。学长 韩版系。学妹 提交于 2019-12-24 13:27:40
#include<iostream> #define OK 1 using namespace std; const int MAX=1e5; const int maxn=1e2+10; const int dot=11;//点的个数; int aov[maxn][maxn];//存图; int voa[maxn][maxn];//逆邻接表; int vis[maxn];//存每个点的入度; int dis[maxn];//存拓扑序列; typedef int status; typedef int person; typedef struct { int *base; int front; int rear; }squeue; squeue Mdancer,Fdancer; void initqueue(squeue &Q)//建立 { Q.base=new person[MAX]; Q.front=Q.rear=0; } void enqueue(squeue &Q,int &e) //入队 { Q.base[Q.rear]=e; Q.rear=(Q.rear+1)%MAX; } void dequeue(squeue &Q,int &e) //出队 { e=Q.base[Q.front]; Q.front=(Q.front+1)%MAX; } person gethead