poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)

 1 /*
 2    题目大意:有N个cows, M个关系
 3    a->b 表示 a认为b  popular;如果还有b->c, 那么就会有a->c 
 4    问最终有多少个cows被其他所有cows认为是popular!
 5    
 6    思路:强连通分量中每两个节点都是可达的! 通过分解得到最后一个连通分量A,
 7    如果将所有的强连通分量看成一个大的节点,那么A一定是孩子节点(因为我们先
 8    完成的是父亲节点的强连通分量)! 最后如果其他的强连通分量都可以指向A,那么
 9    A中的每一个cow都会被其他cows所有的cows认为popular! 
10 */ 
11 #include <string>
12 #include <cstdio>
13 #include <cstring>
14 #include <iostream>
15 #include<vector>
16 #define M 10005
17 using namespace std;
18 
19 vector<int>ex[M];
20 vector<int>ey[M];
21 
22 int n, m;
23 int cnt[M];//记录第一次dfs的节点的逆序
24 int vis[M];//标记节点是否已经被访问过了
25 int mark[M];//标记每一个节点是属于哪一个连通分量
26 int ans;
27 int top;
28 
29 void dfs1(int u){//出度遍历 
30     if(!vis[u]){
31        vis[u]=1;
32        int len=ex[u].size();
33        for(int i=0; i<len; ++i){
34            int v=ex[u][i];
35            dfs1(v);
36        }
37        cnt[top++]=u;
38     }
39 }
40 
41 void dfs2(int u){//入度遍历 
42    if(!vis[u]){
43       vis[u]=1;
44       mark[u]=ans;
45       int len=ey[u].size();
46       for(int i=0; i<len; ++i){
47          int v=ey[u][i];
48          dfs2(v);
49       }
50    }
51 }
52 
53 int main(){
54    while(scanf("%d%d", &n, &m)!=EOF){
55       while(m--){
56          int u, v;
57          scanf("%d%d", &u, &v);
58          ex[u].push_back(v);
59          ey[v].push_back(u);
60       }
61       ans=top=0;
62       for(int i=1; i<=n; ++i)
63          if(!vis[i])
64              dfs1(i);
65       
66       memset(vis, 0, sizeof(vis));
67 
68       for(int i=top-1; i>=0;  --i)
69           if(!vis[cnt[i]]){
70              ++ans;
71              dfs2(cnt[i]);
72           }
73       int count=0;
74       int u=0;
75       for(int i=1; i<=n; ++i)
76            if(mark[i]==ans){
77               ++count;
78               u=i;
79            }
80       memset(vis, 0, sizeof(vis));
81       dfs2(u);
82 
83       for(int i=1; i<=n; ++i)//其他的强连通分量是否都指向了最后一个强连通分量 
84         if(!vis[i]){
85            count=0;
86            break;
87         }
88       printf("%d\n", count);
89       for(int i=1; i<=n; ++i){
90          ex[i].clear();
91          ey[i].clear();
92       }
93       memset(vis, 0, sizeof(vis));
94    }
95    return 0;
96 }

 1 /*
 2 tarjan 算法果然nb! 首先我们利用该算法将所有的强连通分量分开!
 3 然后将每一个连通分量看成是一个点,这样就成了一个有向无环图!
 4 接着判断初度为 0 的点一共有多少个!如果只有一个,那么最终的答案就是
 5 这个节点终所有子节点的个数!也就是说这个节点中的每一个子节点都能 
 6 其他的所有节点到达!
 7 
 8 如果初度为 0 的点多余1个,那么对不起,不能满足某个节点恰好能被其他所有
 9 的节点访问到! 
10 */#include<iostream>
11 #include<cstdio>
12 #include<vector>
13 #include<stack>
14 #include<cstring>
15 #define M 10005
16 using namespace std;
17 
18 vector<int>edge[M];
19 stack<int>s;
20 int low[M], vis[M];
21 int sccN[M], pre[M];
22 int n, m;
23 int dfs_clock, cnt;
24 
25 void dfs(int u){//tarjan 算法 
26    int len = edge[u].size();
27    pre[u]=low[u]=++dfs_clock;
28    s.push(u);
29    for(int i=0; i<len; ++i){
30        int v=edge[u][i];
31        if(!pre[v]){
32           dfs(v);
33           low[u]=min(low[u], low[v]);            
34        } 
35        else if(!sccN[v])
36           low[u] = min(low[u], pre[v]);  
37    }     
38    if(low[u]==pre[u]){
39        ++cnt;
40        while(1){
41          int v=s.top();
42          s.pop();
43          sccN[v]=cnt;
44          if(u==v) break;
45        }           
46    }
47 }
48 
49 int main(){
50    while(scanf("%d%d", &n, &m)!=EOF){
51        dfs_clock=cnt=0;
52        memset(pre, 0, sizeof(pre));
53        memset(sccN, 0, sizeof(sccN));
54        memset(vis, 0, sizeof(vis));
55        while(m--){
56           int u, v;
57           scanf("%d%d", &u, &v);
58           edge[u].push_back(v);           
59        }   
60        for(int i=1; i<=n; ++i)
61           if(!pre[i]) 
62              dfs(i);
63        int num=0;    
64        for(int i=1; i<=n; ++i)
65           if(sccN[i]==1)
66              ++num;
67        int count=0;
68        memset(vis, 0, sizeof(vis));
69        for(int i=1; i<=n; ++i){
70            int len=edge[i].size();
71            for(int j=0; j<len; ++j)
72               if(sccN[i] != sccN[edge[i][j]]){
73                  vis[sccN[i]]=1;
74                  break;
75               }        
76        }
77        
78        for(int i=1; i<=cnt; ++i)
79          if(!vis[i]) ++count;
80        if(count==1)
81           printf("%d\n", num);
82        else printf("0\n");
83        for(int i=1; i<=n; ++i)
84           edge[i].clear();
85        while(!s.empty())
86           s.pop();
87    }
88    return 0;    
89 }
  1 /*比较慢的方法就是:利用tarjan算法将所有的强连通分量进行分离之后,
  2  将每一个强连通分量看成是一个点,如果有满足我们答案的解,那么初度为零
  3  点一定只有一个,并且这个点的所有子节点的编号是 1!那么我们先计算出子节点
  4  编号为 1的个数, 然后在判断其他的强连通分量的节点是否能够到达编号为 1 的
  5  强连通分量! */
  6 #include<iostream>
  7 #include<cstdio>
  8 #include<vector>
  9 #include<stack>
 10 #include<cstring>
 11 #define M 10005
 12 using namespace std;
 13 
 14 vector<int>edge[M];
 15 stack<int>s;
 16 int low[M], vis[M], used[M];
 17 int sccN[M], pre[M];
 18 int n, m;
 19 int dfs_clock, cnt, sum, xx;
 20 
 21 void dfs(int u){
 22    int len = edge[u].size();
 23    pre[u]=low[u]=++dfs_clock;
 24    s.push(u);
 25    for(int i=0; i<len; ++i){
 26        int v=edge[u][i];
 27        if(!pre[v]){
 28           dfs(v);
 29           low[u]=min(low[u], low[v]);            
 30        } 
 31        else if(!sccN[v])
 32           low[u] = min(low[u], pre[v]);  
 33    }     
 34    if(low[u]==pre[u]){
 35        ++cnt;
 36        while(1){
 37          int v=s.top();
 38          s.pop();
 39          sccN[v]=cnt;
 40          if(u==v) break;
 41        }           
 42    }
 43 }
 44 
 45 int dfs2(int u){
 46     int len=edge[u].size();
 47     if(sccN[u]==1){//到达之后就不在进行任何搜索 
 48        sum+=xx;
 49        return 1;         
 50     }
 51     vis[u]=1;
 52     for(int i=0; i<len; ++i){
 53        int v=edge[u][i];
 54        if(!vis[v]){
 55            if(dfs2(v))
 56              return 1;      
 57        }
 58     }     
 59    return 0;
 60 }
 61 
 62 int main(){
 63    while(scanf("%d%d", &n, &m)!=EOF){
 64        dfs_clock=cnt=0;
 65        memset(pre, 0, sizeof(pre));
 66        memset(sccN, 0, sizeof(sccN));
 67        memset(vis, 0, sizeof(vis));
 68        memset(used, 0, sizeof(used));
 69        while(m--){
 70           int u, v;
 71           scanf("%d%d", &u, &v);
 72           edge[u].push_back(v);           
 73        }   
 74        for(int i=1; i<=n; ++i)
 75           if(!pre[i]) 
 76              dfs(i);
 77        int num=0;    
 78        sum=0;
 79        used[1]=1;
 80        for(int i=1; i<=n; ++i){
 81           
 82           if(sccN[i]==1)
 83              ++num;
 84           else if(!used[sccN[i]]){
 85              memset(vis, 0, sizeof(vis));
 86              xx=sccN[i];
 87              used[sccN[i]]=1; 
 88              dfs2(i);
 89           }
 90        }
 91        
 92        if(sum==(cnt+1)*cnt/2-1)//最后将能到达标号为1的连通分量的所有强连通分量的标号加起来 
 93           printf("%d\n", num);
 94        else printf("0\n");
 95        for(int i=1; i<=n; ++i)
 96           edge[i].clear();
 97        while(!s.empty())
 98           s.pop();
 99    }
100    return 0;    
101 }

 


 

 

转载于:https://www.cnblogs.com/hujunzheng/p/3895221.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Uvaoj10054 - The Necklace

1 /*2 题意&#xff1a;打印欧拉回路&#xff01;3 思路&#xff1a;开始时不明白&#xff0c;dfs为什么是后序遍历&#xff1f; 4 因为欧拉回路本身是一条回路&#xff0c;那么我们在dfs时&#xff0c;可能存在提前找到回路&#xff0c;这条回路可能不是欧拉回路&…

s7-1200跟mysql_让西门子S7-1200直接连接MySQL数据库!!!

最近项目上有个需求&#xff0c;要把采集的数据存储到数据库中&#xff0c;当前西门子有很多方法&#xff0c;必读IDB&#xff0c;还有通过WINCC的脚本&#xff0c;第三方的软件等等&#xff0c;但是随着发展&#xff0c;有些需求希望设备直接到数据库&#xff0c;比如云端的RD…

win7个人计算机的ip地址,win7计算机ip地址查询_win7本机ip地址查询

2016-12-09 11:40:21查找计算机的ip地址的方法&#xff1a;点击你的电脑桌面左下角的“开始”找到“运行”点击运行, 在出现的对话框里面输入“cmd” 点击确定然后就会出现一个黑色的命令行窗口,你会看到“&...2016-12-19 15:59:44手机设置静态IP 1、点设置-线网络 2、WLAN…

最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐!

linux环境Mysql 5.7.13安装教程分享给大家&#xff0c;供大家参考&#xff0c;具体内容如下1系统约定安装文件下载目录&#xff1a;/data/softwareMysql目录安装位置&#xff1a;/usr/local/mysql数据库保存位置&#xff1a;/data/mysql日志保存位置&#xff1a;/data/log/mysq…

iis 日志 post数据_云原生日志的趋势(1):logscape和logiq

作为日志产品的PM&#xff0c;跟进国内外日志产品动向是个长期工作。这几天翻新一些历史记录&#xff0c;发现logscape自2017年开源以来&#xff0c;突然2019年10月又更新了一会。于是顺着翻翻logscape的github账号&#xff0c;起了兴致来写点文字。https://github.com/logscap…

大学计算机基础总结,大学计算机基础第二章总结

数&#xff1a;计算机的数据的基本形态是二进制数数制&#xff1a;可以直接进行数学计算数字码制&#xff1a;用来表示不同对象属性● 数制(计数体制)多位数中每一位的构成方法以及实现从低位到高位的进位规则(也叫做进制)▲ 常用数制&#xff1a;R进制有R个数码&#xff0c;数…

获取list泛型_泛型

泛型什么是泛型&#xff1f;为什么使用泛型&#xff1f;泛型的出现意味着编写的代码可以被不同类型的对象所重用&#xff0c;提升了代码的重用性。泛型的本质是参数化类型&#xff0c;即将所需操作的数据类型设置为一个参数。 举个实际中的栗子&#xff1a;我们需要设计一个柜子…

w10计算机字体怎么设置在哪里设置,如何设置修改win10系统电脑的显示字体

如何设置修改win10系统电脑的显示字体腾讯视频/爱奇艺/优酷/外卖 充值4折起今天给大家介绍一下如何设置修改win10系统电脑的显示字体的具体操作步骤。1. 首先鼠标左键开始&#xff0c;然后在菜单下的左下角选择设置图标。2. 进入Windows 设置后&#xff0c;单击个性化。3. 接着…

powerdesigner mysql 自增主键_PowerDesigner Mysql 主键自增、初始值、字符集

自增在你所要设为自增型的键上(比如你的id)双击&#xff0c;弹出一个Column Properties对话框&#xff0c;右下角有一个Identify的选择框&#xff0c;选中它OK&#xff0c;就可以了。 再去查看Preview&#xff0c;就能看到AUTO_INCREMENT。起始值默认自增字段从1开始, 如果需要…

计算机设置从u盘启动怎么办,电脑设置从u盘启动盘启动出现蓝屏该怎么解决?

电脑设置从u盘启动蓝屏怎么办?我们在电脑遇到系统等问题时&#xff0c;经常会选择使用u盘重装系统&#xff0c;这种重装方式可以说是目前最便捷实用的了。但是最近又有用户反映将U盘设置为第一启动项后&#xff0c;电脑没办法从u盘启动&#xff0c;出现了蓝屏的情况&#xff0…

ambari mysql jar_从零开始安装 Ambari (3) -- 安装 Ambari

1. 安装yum -y install ambari-server2. ambari server 需要一个数据库存储元数据&#xff0c;默认使用的 Postgres 数据库。默认的用户名和密码是&#xff1a; ambari/bigdata 。但是一般情况下&#xff0c;后面还要安装 hive 和 Ranger&#xff0c;也需要一个存元数据的数据库…

服务器2012系统在dos卸载,Windows系统下彻底删除Windows.old 文件夹的方法

系统是直接硬盘安装的&#xff0c;导致c盘产生了旧系统的文件夹Windows.old&#xff0c;占用很大的磁盘空间&#xff0c;删也删不掉&#xff0c;咋办&#xff1f;不要紧&#xff0c;下面大神来教你神操作&#xff01;&#xff01;&#xff01;1、打开“计算机”&#xff0c;选择…

backupexec mysql_MySQL备份可能遇到的坑

MySQL备份工具&#xff0c;支持各种参数选项&#xff0c;使用不同的选项极有可能影响备份处理过程。本文使用我们常规认为合理的备份参数&#xff0c;测试/验证是否存在容易忽视的坑# 常规备份参数# mysqldumpshell> mysqldump --single-transaction --master-data2 -B repl…

win10虚拟机服务器错误怎么解决方法,虚拟机下安装win10系统后出现升级报错故障的解决方法【图文】...

现在的win10还是很挑系统的&#xff0c;兼容性有待进一步增强。有些在虚拟机环境下安装了win10的小伙伴&#xff0c;升级是很可能报以下错误的&#xff0c;升级你的ESX版本吧&#xff0c;5.5以下升级win10基本都是没戏的。VM workstation11以上是明确支持win10。不能升级win10怎…

mysql客户端修改sqlmode_MySQL修改sql_mode

一 ERR 1067引发的血案今天在Navicat中运行sql语句创建数据表出现了错误Err 1067。而这条语句在有些同事的mysql上是正确的&#xff0c;但是在有些人那里就报错。QQ截图20170811143551.png原因竟然是timestamp的默认值不正确。查阅资料得知&#xff0c;mysql5.7版本中有了一个S…

零基础mysql项目实例_MySQL-零基础开发

1.终端下连接mysql服务mysql -uroot -p回车后输入设定的密码即可。进去后每条命令结尾要带分号&#xff1b;退出命令exit单行注释有两种&#xff1a;#  或 --空格。多行注释/*  */2.基本命令集合针对数据库&#xff1a;use sys;  show databases;查看当前操作的数据库&a…

php设置mysql 编码_php怎么设置mysql编码?

在php中&#xff0c;可以使用mysql_query()函数来设置mysql编码&#xff0c;语法“mysql_query(SET NAMES 编码方式);”&#xff1b;mysql_query()函数需要放置在mysql_connect()语句之后。在php中&#xff0c;可以使用mysql_query()函数来设置mysql编码。在PHP连接数据库的时候…

golang 切片 接口_Go编程模式:切片,接口,时间和性能

在本篇文章中&#xff0c;我会对 Go 语言编程模式的一些基本技术和要点&#xff0c;这样可以让你更容易掌握 Go 语言编程。其中&#xff0c;主要包括&#xff0c;数组切片的一些小坑&#xff0c;还有接口编程&#xff0c;以及时间和程序运行性能相关的话题。本文是全系列中第 1…

poj 3352Road Construction(无向双连通分量的分解)

1 /*2 题意&#xff1a;给定一个连通的无向图G&#xff0c;至少要添加几条边&#xff0c;才能使其变为强连通图&#xff08;指的是边强联通&#xff09;。 3 思路&#xff1a;利用tarjan算法找出所有的双联通分量&#xff01;然后根据low[]值的不同将双联通分量4 进行…

jsp中去掉超链接下划线吗_网页中如何去掉超链接的下划线

展开全部a:link {text-decoration: none;}a:visited {text-decoration: none;color: #6B6C70;}其中的text-decoration: none;是消除下划线例如&#xff1a;只需加入一段代码32313133353236313431303231363533e59b9ee7ad9431333337393534&#xff1a;td,body { font-size: 9pt}a…