拓扑排序

POJ2367(拓扑排序裸题

跟風遠走 提交于 2019-12-05 09:16:32
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 using namespace std; 5 typedef long long ll; 6 const int N = 150; 7 int in[N],n,r; 8 vector<int>ans; 9 vector<int>edge[N]; 10 priority_queue<int,vector<int>,greater<int> >priq; 11 int main(){ 12 ios::sync_with_stdio(0); 13 cin>>n; 14 for(int i = 1;i <= n;++i){ 15 while(cin>>r){ 16 if(r==0)break; 17 edge[i].push_back(r);in[r]++; 18 } 19 } 20 for(int i = 1;i <= n;++i)if(in[i]==0)priq.push(i); 21 while(!priq.empty()){ 22 23 int p = priq.top();priq.pop(); 24 ans.push_back(p); 25 for(int j = 0;j < edge[p].size();++j){ 26 int y = edge[p][j]

CSP2019总结

别说谁变了你拦得住时间么 提交于 2019-12-05 09:06:27
话说 我已经写过游记了 但是老师要求我再写一篇 \(QAQ\) 考试总结嘛 在这里 这次主要总结下 现在欠缺&&不扎实的知识 以及需要学习的算法 和努力方向 不足的知识 \(top1\) : \(DP\) 当然是 \(DP\) 了啊 补缺方向:啥都要补 树上的一些算法 板子题会,但变体就不会了 这点得靠刷题来拯救 数论 这点只能看 \(RP\) 刷题都拯救不了 数据结构 线段树的题 我大概想得出来 主席树挑战一下 也勉强行 但树链剖分 和 左偏树的题就不在我的能力范围内了 努力方向:先巩固树链剖分,再回顾莫队,然后学习分块和珂朵莉树 多骗分 舞蹈链 按老师的进度应该已经会了 但我当时漏掉了 这点得补上 拓扑排序 写很简单 主要是在很多题当中都用的到 而判断是否得用拓扑排序 就得靠练习了 努力方向:多刷一些拓扑排序的题 网络流 这方面我做题太少了 也得多刷题 二分图匹配 我基本上没做过什么题 很不熟悉 历年真题 三年 中考 ,CSP嘛 经典题目 USACO上的 书上的例题 总结一下 多刷题 这是hyz大佬给予我的点评 多打比赛 模拟考试环境 给予自己一个限时的测试是必要的 多刷杂题 即不看标签做题 有利于提高编程能力 最后 膜拜 hyz巨佬 tql 我还要膜拜我的学弟们 每一个都比我强 考试经验总结 这次 \(CSP\) 的难度飙升大家是有目共睹的 然后 纯暴力 能上 \(300=\

P1983 车站分级 思维+拓扑排序

五迷三道 提交于 2019-12-05 07:43:20
很久以前的一道暑假集训的题,忘了补。 感觉就是思维建图,加拓扑排序。 未停靠的火车站,必然比停靠的火车站等级低,就可以以此来建边,此处注意用vis来维护一下,一个起点和终点只建立一条边,因为不这样的话会重复建边。 虽然重复建边拓扑排序的时候,统计入度,更新入度的时候完全不影响结果,因为这个重复的点和入度都统计了,也都会在拓扑的删去,答案依然正确。 但是重复建边vector会弄的很大,导致MLE(我debug好久才发现MLE的原因)。洛谷上只能get到80分,加了vis就100了。 主要是思维吧,未经过的点向经过点建边,拓扑找每个点所属的层数,最后统计答案即可。 代码如下: 1 #include <bits/stdc++.h> 2 #define debug(x) cout << #x << ": " << x << endl 3 using namespace std; 4 typedef long long ll; 5 6 const int MAXN=1024; 7 const int INF=0x3f3f3f3f; 8 const int MOD=1e9+7; 9 10 int in[MAXN],lv[MAXN],stay[MAXN]; 11 bool is[MAXN]; 12 bool vis[MAXN][MAXN]; 13 vector<int> to[MAXN]; 14

拓扑排序

纵然是瞬间 提交于 2019-12-04 17:52:57
大概解决问题:给定优先级关系,输出依次顺序 方法:先把最低级的放入vector,最后反向输出即可。 #include<bits/stdc++.h> using namespace std; const int MAXN=30030; bool vis[MAXN]; int in[MAXN]; int ans; vector<int> edge[MAXN]; int main() { int T; cin>>T; int n,m,a,b; while(T--) { scanf("%d%d",&n,&m); memset(in,0,sizeof(in)); for (int i=1;i<=n;i++) edge[i].clear(); for (int i=0;i<m;i++) { scanf("%d%d",&a,&b); in[a]++; edge[b].push_back(a); } priority_queue<int>q; for (int i=1;i<=n;i++) { if(!in[i]) q.push(i); } vector<int>v; ans=0; while(!q.empty()) { ans++; a=q.top(); v.push_back(a); cout<<a<<" 进队"<<endl; q.pop(); vis[a]=1; for (int i=0;i

9.6偏序关系

谁都会走 提交于 2019-12-04 13:41:18
9.6偏序关系(Partial Order) 偏序(Partial Order) 定义: 偏序(Partial order):定义在A上的集合R是偏序关系iff(当且仅当)其具有以下性质: 自反性(reflexive) 反对称性(antisymmetric) 传递性(transtive) NOTE: R记作≼,注意这里的≼不必是指一般意义上的“小于或等于”, 若有x≼y,我们也说x排在y前面(x precedes y). 偏序集(Partially ordered set)/(或简写为poset): 集合A及定义在其上的偏序关系R一起称为偏序集,记作(A, R),A中的元素也称为偏序集中的元素. 线序/全序(Linear Order) 如果(A, ≤)是一个偏序集(poset),那么对于其中的元素a和b, a≤b 或者 b≤a,那么称为可比的(Comparable) 即不存在a≤b,也不存在b≤a,那么称为不可比的(Imcomparable) 如果偏序集A中每对元素(every pair of elements)都是可比的,那么我们就称A是线序集合(linearly ordered set)或全序集合(totally ordered set),称偏序关系R为线序或全序关系(linear order). 我们也称A为链(chain). 良序集(Well-ordered set) 定义

DAG及拓扑排序

喜你入骨 提交于 2019-12-04 09:33:17
1.有向无环图和拓扑排序 有向无环图( Directed Acyclic Graph,简称DAG );拓扑排序指的对DAG一个有序的线性排列。 https://github.com/WuYiMi/Myrepository/blob/master/DS/Graph.java 来源: https://www.cnblogs.com/lbrs/p/11854044.html

拓扑排序-学习笔记

十年热恋 提交于 2019-12-04 07:51:56
定义 对一个有向无环图(Directed Acyclic Graph简称DAG)$G$进行拓扑排序,是将$G$中所有顶点排成一个线性序列,使得图中任意一对顶点$u$和$v$,若边$(u,v)∈E(G)$,则$u$在线性序列中出现在$v$之前。 实现步骤 在有向图中选一个没有前驱的顶点并且输出 删除所有和它有关的边 重复上述两步,直至所有顶点输出,或者当前图中不存在无前驱的顶点。后者代表我们的有向图是有环的,因此,也可以通过拓扑排序来判断一个图是否有环。 无向图的判环 环上的点 度数$>=2$ (与环外的点有边时 度数$>2$) 删除所有度$<=1$的顶点及相关的边,并将另外与这些边相关的其它点的度减$1$ 将度数变为$1$的点重复上步骤 如果最后还有未删除顶点,则存在环,否则没有环 1 void tp() 2 { 3 for(int i=1;i<=n;i++) 4 if(ind[i]==0) 5 Q.push(i); 6 while(!Q.empty()) 7 { 8 int u=Q.front(); 9 Q.pop(); 10 ans[++cnt]=u; 11 for(int i=0;i<G[u].size();i++) 12 { 13 int v=G[u][i]; 14 ind[v]--; 15 if(ind[v]==0) 16 Q.push(v); 17 } 18 } 19

USACO4.4 Frame Up【拓扑排序】

断了今生、忘了曾经 提交于 2019-12-04 07:51:09
题意居然还读了好久... 读完题目之后大概就知道拓扑排序了。用拓扑可以求出一些字母之间的关系,谁先,谁后。但是这个关系不是唯一确定的,所以就会产生多种方案(题目还要求按字典序输出所有的方案) 输出方案要麻烦一些,最刚开始还没有想到。可以用一个$dfs$,当这个点的入度变为$0$之后,就输出,递归到下一层,然后再回溯。 按字母的字典序枚举就可以输出按字典序排的方案。 1 /* 2 ID: Starry21 3 LANG: C++ 4 TASK: frameup 5 */ 6 #include<cstdio> 7 #include<algorithm> 8 #include<vector> 9 #include<cstring> 10 #include<queue> 11 #include<map> 12 #include<iostream> 13 using namespace std; 14 #define ll long long 15 #define INF 0x3f3f3f3f 16 #define N 35 17 int h,w,n/*一共n个图像(字母)*/; 18 char mp[N][N];//存图 19 int s[N],x[N],z[N],y[N];//每个字母边框的上下左右边在哪一行(列) 20 char kd[N];//存字母(1~n) 21 bool vis

[题目]拓扑排序

时光怂恿深爱的人放手 提交于 2019-12-04 06:19:09
拓扑排序 P3243 [HNOI2015]菜肴制作:注意到题面要求先1尽量靠前,然后2尽量靠前,然后。。。 其实是贪心,需要建反图然后拿大根堆去跑,原因:我们先从可能成为最后的点中挑一个最大的出来(肯定是不劣的),然后把他的所有后继节点插入,此时我们接着取最大的;这样我们相当于先取能用的点中最大的点,尽量后取更小的点,所以我们能够把更小的点尽量向前放。 inline void main() { T=g(); while(T--) { cnt=tot=0; priority_queue<int> q; memset(fir,0,sizeof fir),memset(in,0,sizeof in); n=g(),m=g(); for(R i=1,u,v;i<=m;++i) u=g(),v=g(),add(v,u); for(R i=1;i<=n;++i) if(!in[i]) q.push(i); while(q.size()) { R u=q.top(); q.pop(); ans[++tot]=u; for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; if(--in[v]==0) q.push(v); } } if(tot<n) {puts("Impossible!"); continue;} for(R i=n;i;--i) printf("%d "

【模板】拓扑排序

牧云@^-^@ 提交于 2019-12-04 01:15:18
模板题 还有6天CSP-S,慌得一批 #include<bits/stdc++.h> using namespace std; int head[3000005],v[3000005],n,sum,l,end[3000005],rdu[3000500]; queue<int>q; struct node { int to,next; } a[2000005]; inline void add(int from,int to) { a[++l].to=to; a[l].next=head[from]; head[from]=l; rdu[to]++; } int tp() { int ans=0; for(int i=1; i<=n; i++) if(!rdu[i])q.push(i); while(q.size()) { int x=q.front(); q.pop(); end[x]+=v[x]; ans=ans>end[x]?ans:end[x]; for(register int i=head[x]; i; i=a[i].next) { rdu[a[i].to]--; end[a[i].to]=end[a[i].to]>end[x]?end[a[i].to]:end[x]; if(!rdu[a[i].to])q.push(a[i].to); } } return ans; }