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的更多相关文章

  1. Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序

    Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序 [Problem Description] ​ 给你 ...

  2. Educational Codeforces Round 72 (Rated for Div. 2)

    https://www.cnblogs.com/31415926535x/p/11601964.html 这场只做了前四道,,感觉学到的东西也很多,,最后两道数据结构的题没有补... A. Creat ...

  3. 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 ...

  4. 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 ...

  5. Educational Codeforces Round 72 (Rated for Div. 2) B题

    Problem Description: You are fighting with Zmei Gorynich — a ferocious monster from Slavic myths, a ...

  6. 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 ...

  7. Coloring Edges(有向图环染色)-- Educational Codeforces Round 72 (Rated for Div. 2)

    题意:https://codeforc.es/contest/1217/problem/D 给你一个有向图,要求一个循环里不能有相同颜色的边,问你最小要几种颜色染色,怎么染色? 思路: 如果没有环,那 ...

  8. Educational Codeforces Round 72 (Rated for Div. 2)E(线段树,思维)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;#define BUF_SIZE 100000 ...

  9. 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 ...

随机推荐

  1. Linux - top命令监控列表的详细解析

    统计信息区(系统资源信息区) 前五行,即列表上方的五行 第一行:输出系统任务队列信息 18:46:38:系统当前时间 up 2days 1:54:系统开机后到现在的总运行时间 1 user:当前登录用 ...

  2. jenkins-gitlab-harbor-ceph基于Kubernetes的CI/CD运用(三)

    从最基础镜像到业务容器 构建 [为gitlab项目部署做铺垫] 业务镜像设计规划 目录结构 # pwd /data/k8s/app/myapp # tree . . ├── dockerfile │  ...

  3. Selenium系列(二) - 控制浏览器操作的详细解读

    如果你还不想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识 ...

  4. Cisco 综合配置(三)

    要求: 1.PC1 PC2使用DHCP,获取IP ,VLAN为10 和20,网关在Core Switch 2上2.DHCP和web server VLAN为100,网关在Core Switch 1上3 ...

  5. springMVC容器简介和执行流程

    先来看一下,初始化的大体流程:  然后,我们再来看一下,我们的控制器DispatcherServlet的类图及继承关系.  系统启动的时候根据配置文件创建spring的容器, 首先是发送http请求到 ...

  6. CF1324B Yet Another Palindrome Problem 题解

    原题链接 CF 127个测试点,好评 简要题意: 多组数据,问数组中是否有长度 \(\geq 3\) 的回文子序列. 我们需要找到本质. 题目不让我们求这个长度,只让我们判断,这是为什么呢? 如果答案 ...

  7. 洛谷 P3909 异或之积 题解

    原题链接 本人看了其它解法,发现本人的解法还是 首创 ! 而且我的解法好像和 \(\times 6\) 没什么关系 -- (如果没 \(\times 6\),我没还不用算逆元) 别人的思路呢,大都是从 ...

  8. 切比雪夫低副瓣阵列设计 MATLAB

    相控阵天线中,直线阵列作为重要的一种,有着极为广泛的应用.切比雪夫低副瓣阵列设计是一种典型的设计方法. 切比雪夫方法主要是实现低副瓣.窄波束: 其产生的核心如下: 我的理解:因为能量守恒,所有副瓣都一 ...

  9. UVa 11059 最大乘积 java 暴力破解

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  10. TPYBoard v202开发板通过I2C协议驱动oled

    最近无聊的时候研究了一下TPYBoard v202开发板,发现网上TPYBoard开发驱动oled的这块资料比较少,本人测试成功后给大家分享一下经验 下面通过代码讲解一下 1.首先需要导包, 在网上下 ...