拓扑排序入门详解&&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 ...
 
随机推荐
- BAPC K题 Keep Him Inside
			
Problem Statement: As a result of a long-standing war between the Sorcerers and the Orcs, you have b ...
 - [剑指offer]14-1.剪绳子
			
14-1.剪绳子 方法一 动态规划 思路:递归式为f(n)=max(f(i), f(n-i)),i=1,2,...,n-1 虽然我现在也没有彻底明白这个递归式是怎么来的,但用的时候还是要注意一下.f( ...
 - [树的深度] Party
			
Party A company has n employees numbered from 1 to n. Each employee either has no immediate manager ...
 - effective-java学习笔记---注解优于命名模式39
			
命名模式的缺点有以下三点:(在第 4 版之前,JUnit 测试框架要求其用户通过以 test[Beck04] 开始名称来指定测试方法) 1.拼写错误导致失败,但不会提示. 2.无法确保它们仅用于适当的 ...
 - macOS 去掉系统软件更新红点提示
			
当前系统提示更新到macOS Catalina .打开终端执行以下命令: 第一步运行: sudo softwareupdate --ignore "macOS Catalina" ...
 - ClickHouse学习系列之二【用户权限管理】
			
背景 最近花了些时间看了下ClickHouse文档,发现它在OLAP方面表现很优异,而且相对也比较轻量和简单,所以准备入门了解下该数据库系统.在安装完之后首先做的应该如何设置用户密码以及权限控制.因为 ...
 - 【LeetCode】141.环形链表
			
题目描述 141.环形链表 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 -1,则在该链表中 ...
 - 使用Git pull文件时,出现"error: RPC failed; curl 18 transfer closed with outstanding read data remaining"
			
error: RPC failed; curl transfer closed with outstanding read data remaining fatal: The remote end h ...
 - [noip模拟赛]某种数列问题<dp>
			
某种数列问题 (jx.cpp/c/pas) 1000MS 256MB 众所周知,chenzeyu97有无数的妹子(阿掉!>_<),而且他还有很多恶趣味的问题,继上次纠结于一排妹子的排法以 ...
 - thinkphp5.1中使用链式操作的坑
			
1.在进行tp5->tp5.1的时候,没有想太多,直接使用之前的代码:结果在该操作中,多次调用该get方法,tp5.1的链式操作一直保持了之前的搜索条件,截图如下:(具体的代码没有展示) 2.然 ...