拓扑排序入门详解&&Educational Codeforces Round 72 (Rated for Div. 2)-----D
https://codeforces.com/contest/1217
D:给定一个有向图,给图染色,使图中的环不只由一种颜色构成,输出每一条边的颜色
不成环的边全部用1染色
ps:最后输出需要注意,一个环上的序号必然是非全递增的,若有环且有一条边u->v,u的序号<v则输出1否则输出2(反过来也可以)
可以用dfs染色或者用拓扑排序做
顺便复习一下拓扑排序:
拓扑排序是将有向无环图的所有顶点排成一个线性序列,使得图中任意两个顶点u,v若存在u->v,那么序列中u一定在v前面。
了解一个概念: DAG-->有向无环图,一个有向图的任意顶点都无法通过一些有向边回到自身,称之为DAG
算法过程:
(1)定义一个队列,把所有入度为0的结点加入队列(图有n个点)
(2)取队首节点,输出,删除所有从他出发的边,并令这些边的入度-1,若某个顶点的入度减为0,则将其加入队列
(3)反复进行(2)操作,直到队列为空;
注意:若队列为空时入过队的节点数目恰好为n,说明拓扑排序成功,图为DAG,否则图中有环
这位博主写的挺好的 https://blog.csdn.net/qq_41713256/article/details/80805338

#include<bits/stdc++.h>
using namespace std;
inline int read(){
,w=;;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
/*-------------------------------------------------------------------*/
typedef long long ll;
;
int du[maxn];
ll cnt;
int n,m;
int s;
vector<int>G[maxn];
pair<int,int>ans[maxn];
queue<int>q;
int main()
{
ios_base::sync_with_stdio(); cin.tie(); cout.tie();
//一个环上的序号必然是非全递增的
cin>>n>>m;
;i<=m;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
ans[i].first=u;ans[i].second=v;
//入度
du[v]++;
}
;i<=n;i++) ) q.push(i);
while(!q.empty()){
int now=q.front();q.pop();
int len=G[now].size();
;i<len;i++){
du[G[now][i]]--;//该点入度-1
)q.push(G[now][i]);
}
}
;
;i<=n;i++)
){
flag=;//标记是否还存在入度不为0的点
break;
}
//一个环上的序号必然是非全递增的
if(flag){//说明有环
cout<<<<endl;
//for(int i=1;i<=m;i++)cout<<1<<" ";
;i<=m;i++){
if(ans[i].first>ans[i].second)
cout<<<<" ";
<<" ";
}
}
else{ //无环直接输出1
cout<<<<endl;
;i<=m;i++)
cout<<<<" ";
}
;
}
DFS版:
dfs过程中有3个状态1,-1,0,1表示当前搜索路径,-1表示已搜索过且无环路径,0表示还未搜索,可以用前向星存边或者vector存边过
其他需要注意的代码有注释
ps:讲个大家不容易理解的地方,这个DFS的点是不是可以从任意起点搜索?答案:是的,这个对拓扑序列没有影响,可通过代码自由验证。
在有向图DFS过程中(不判环的情况下),我们用栈去存储他的拓扑序列,当一个点没有后驱节点时,这个节点入栈,记住栈的性质(后进先出),然后回溯,这样,越是后面的节点就会被压进栈底
比如说有向边u->v,u是v的前驱,若存在u->v>t,t在拓扑序列中一定在u的后面(拓扑排序的性质),我们从v开始搜索,到t终止(无后驱节点),回溯,入栈,v入栈,回溯。
最后我们搜索u,发现u的后驱节点已标记,所以入栈,退出完成拓扑排序
所以,以DFS回溯+栈的形式就可以很好地完成一次拓扑排序
前向星版本:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
,w=;;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
/*-------------------------------------------------------------------*/
typedef long long ll;
;
struct node{
int to,next;
}star[];
ll cnt;
int n,m;
int vis[maxn],head[maxn];
void add(int u,int v){
star[cnt].to=v;
star[cnt].next=head[u];
head[u]=cnt++;
}
bool dfs(int idx){
vis[idx]=;
;i=star[i].next){
int v=star[i].to;
)return false;
//若搜索过程中发现回到本次搜索过的点,说明有环,退出
&&!dfs(v))return false;
}
vis[idx]=-;//目前路径上不存在环,所以标记为-1
return true;
}
pair<int,int >p[maxn];
int main()
{
ios_base::sync_with_stdio(); cin.tie(); cout.tie();
//一个环上的序号必然是非全递增的
memset(head,-,sizeof(head));
cin>>n>>m;
;i<=m;i++){
int u,v;
cin>>u>>v;
add(u,v);
p[i].first=u,p[i].second=v;
}
;
;i<=n;++i){
if(!vis[i]){
if(!dfs(i)){
flag=;
break;
}
}
}
if(flag){
cout<<<<endl;
;i<=m;i++){
<<" ";
<<" ";
}
}
else{
cout<<<<endl;
;i<=m;i++){
cout<<<<" ";
}
}
;
}
vector版本:
#include<bits/stdc++.h>
using namespace std;
inline int read(){
,w=;;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
/*-------------------------------------------------------------------*/
typedef long long ll;
;
struct node{
int to,next;
}star[];
vector<int>edge[maxn];
ll cnt;
int n,m;
int vis[maxn],head[maxn];
bool dfs(int idx){
int len=edge[idx].size();
vis[idx]=;
;i<len;++i){
);
;
}
vis[idx]=-;
;
}
pair<int,int >p[maxn];
int main()
{
ios_base::sync_with_stdio(); cin.tie(); cout.tie();
//一个环上的序号必然是非全递增的
memset(head,-,sizeof(head));
cin>>n>>m;
;i<=m;i++){
int u,v;
cin>>u>>v;
p[i].first=u,p[i].second=v;
edge[u].push_back(v);
}
;
;i<=n;++i){
if(!vis[i]){
if(!dfs(i)){
flag=;
break;
}
}
}
if(flag){
cout<<<<endl;
;i<=m;i++){
<<" ";
<<" ";
}
}
else{
cout<<<<endl;
;i<=m;i++){
cout<<<<" ";
}
}
;
}
对拓扑排序讲得还不错的博客:深入理解拓扑排序(Topological sort) - 简书 https://www.jianshu.com/p/3347f54a3187拓扑排序dfs版+判环_Python_姬小野的博客-CSDN博客 https://blog.csdn.net/wjh2622075127/article/details/82712940
拓扑排序入门详解&&Educational Codeforces Round 72 (Rated for Div. 2)-----D的更多相关文章
- Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序
Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序 [Problem Description] 给你 ...
- Educational Codeforces Round 72 (Rated for Div. 2)
https://www.cnblogs.com/31415926535x/p/11601964.html 这场只做了前四道,,感觉学到的东西也很多,,最后两道数据结构的题没有补... A. Creat ...
- Educational Codeforces Round 72 (Rated for Div. 2) Solution
传送门 A. Creating a Character 设读入的数据分别为 $a,b,c$ 对于一种合法的分配,设分了 $x$ 给 $a$ 那么有 $a+x>b+(c-x)$,整理得到 $x&g ...
- Educational Codeforces Round 72 (Rated for Div. 2) C题
C. The Number Of Good Substrings Problem Description: You are given a binary string s (recall that a ...
- Educational Codeforces Round 72 (Rated for Div. 2) B题
Problem Description: You are fighting with Zmei Gorynich — a ferocious monster from Slavic myths, a ...
- Educational Codeforces Round 72 (Rated for Div. 2) A题
Problem Description: You play your favourite game yet another time. You chose the character you didn ...
- Coloring Edges(有向图环染色)-- Educational Codeforces Round 72 (Rated for Div. 2)
题意:https://codeforc.es/contest/1217/problem/D 给你一个有向图,要求一个循环里不能有相同颜色的边,问你最小要几种颜色染色,怎么染色? 思路: 如果没有环,那 ...
- Educational Codeforces Round 72 (Rated for Div. 2)E(线段树,思维)
#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;#define BUF_SIZE 100000 ...
- Educational Codeforces Round 72 (Rated for Div. 2)C(暴力)
#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;char s[200007];int a[20 ...
随机推荐
- BigDecimal介绍及BigDecimal实现四舍五入
BigDecimal介绍及BigDecimal实现四舍五入 BigDecimal是什么? 我们知道float最大精度是7-8位有效数字,而double的最大精度是16-17位有效数字,那么大于16位的 ...
- Socket编程简介
目录 背景 基础 流程 参考 本文系读书笔记,非深入研究,也无代码,如非所需,请见谅. 哦,这里有份不错的:Linux的SOCKET编程详解 背景 花了好久的时间(大约一周,我太垃圾)看完了一篇英文文 ...
- SpringMVC框架——转发与重定向
网上摘取一段大神总结的转发与重定向的区别,如下: 转发(服务端行为) 形式:request.getRequestDispatcher().forward(request,response) 转发在服务 ...
- 记录一次云主机部署openstack的血泪史
看见这个部署成功的留下了激动的泪水 经过长时间的BUG苦肝终于成功部署成功 部署的环境2vCPU 8GB 阿里云主机,部署成功以后内存占用确实蛮高的 记录这一次踩坑,给后来者避免踩坑时间,个人踩坑踩 ...
- identityserver4源码解析_2_元数据接口
目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4 ...
- hdu3336 Counting the string kmp的next数组的应用
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3336/ 题意就是要求一个字符串的所有前缀在字符串中出现的次数之和,我们容易想到kmp中的next数组,next[ ...
- centos 安装activeMq
Apache ActiveMQ是一个免费的开源消息代理和集成模式服务器.它支持来自JAVA.c++.C.Python.Perl.PHP等多种语言的客户端和协议.它提供了许多功能,如消息组.虚拟目的地. ...
- 从sslyze看TLS证书的点点滴滴
纵观眼下,https已经深入大街小巷,成为网络生活中不可或缺的一部分了.提到了https,我们又不得不想到TLS(SSL),而提到了TLS,我们又不得不提到一个让人捉摸不透的东西:TLS证书. 关于证 ...
- python之道15
请实现一个装饰器,限制该函数被调用的频率,如10秒一次(借助于time模块,time.time())(面试题,有点难度,可先做其他) 答案 # 思路 运行不能用 import time def wra ...
- Serpent.AI - 游戏代理框架(Python)
Serpent.AI - 游戏代理框架(Python) Serpent.AI是一个简单而强大的新颖框架,可帮助开发人员创建游戏代理.将您拥有的任何视频游戏变成一个成熟的实验的沙箱环境,所有这些都是熟悉 ...