【HDU - 1269】迷宫城堡 (tarjan算法模板)

题干:

为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间。Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。 

Input

输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。 

Output

对于输入的每组数据,如果任意两个房间都是相互连接的,输出"Yes",否则输出"No"。 

Sample Input

3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0

Sample Output

Yes
No

解题报告:

    这题做法很多,也可以直接暴力跑每个节点是否可以连通其他节点,也可以直接跑tarjan算法看是否只有一个强连通分量。

 

AC代码:

#include<cstdio>
#include<stack>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN = 10000 + 5;
const int MAXM = 100000 + 5;
int n,m;
int top,tot,cnt;
int head[MAXN];
bool vis[MAXN];
int dfn[MAXN],low[MAXN];
stack<int> sk;
struct Edge {int to,ne;
}e[MAXM]; 
void add(int u,int v) {e[++top].to = v;e[top].ne = head[u];head[u] = top;
}
void tarjan(int x) {low[x] = dfn[x] = ++tot;sk.push(x);vis[x] = 1;for(int i = head[x]; i!=-1; i=e[i].ne) {int v = e[i].to;if(dfn[v] == 0) {tarjan(v);low[x] = min(low[x],low[v]);}else if(vis[v] == 1) {low[x] = min(low[x],dfn[v]);}}if(low[x] == dfn[x]) {cnt++;while(1) {int now = sk.top();sk.pop();vis[now]=0;if(now == x) break;}}}
int main()
{int a,b;while(~scanf("%d%d",&n,&m)) {if(n == 0 && m == 0) break;top = tot = cnt = 0;while(sk.size()) sk.pop();memset(head,-1,sizeof head);memset(vis,0,sizeof vis);for(int i = 1; i<=n; i++) dfn[i] = low[i] = 0;for(int i = 1; i<=m; i++) {scanf("%d%d",&a,&b);add(a,b);}for(int i = 1; i<=n; i++) {if(dfn[i] == 0) tarjan(i);}if(cnt == 1) puts("Yes");else puts("No");}return 0 ;
}

直接暴力AC代码2:

//hdu1269(迷宫城堡&&判断有向图是否联通)
//题目大意:已知有n(n<=10000)个点,M(M<=100000)个道路。每条道路都是单向的。求任意两个点之间是否联通?
//解题思路:由于点n的范围较大,所以用邻接表存储n个点的道路情况。然后依次搜索n各点能否
//到达剩余的n-1个点。如果有一个不满足,就退出循环。表示该有向图不是联通图。否则就是。
//这里我用的是dfs搜索看是否某个点能否到达其余的n-1个点。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,head[100010],k,flag,vis[10010],cnt,gg;
struct node {int x,y;int next;
} edge[100010];
void init() {                      //初始化邻接表k=0;memset(head,-1,sizeof(head));
}
void input() {                 //读取数据init();int i,j,x,y;for(i=0; i<m; i++) {scanf("%d%d",&x,&y);edge[k].x=x;edge[k].y=y;edge[k].next=head[x];      //建x到y的边。head[x]=k++;}
}
void dfs(int x) {int v,i;if(cnt==n-1) {//可以到达其余的n-1个点gg=1;return;     }            for(i=head[x]; i!=-1; i=edge[i].next) {v=edge[i].y;if(!vis[v]) {vis[v]=1;cnt++;                    //cnt用来记录从某点出发所能到达的点数dfs(v);if(gg) return;}}
}
int main() {int i,j;while(scanf("%d%d",&n,&m)&&(n|m)) {input();flag=1;for(i=1; i<=n; i++) {cnt=0;gg=0;memset(vis,0,sizeof(vis));vis[i]=1;          //标记idfs(i);                  //搜索i所能到达的点的个数。if(cnt<n-1) {flag=0;break;	      //有一个点到其余各点不是n-1时,则该图不联通。}                     //退出循环}if(flag==1) printf("Yes\n");else        printf("No\n");}return 0;
}

新的算法(kosaraju算法):(https://blog.csdn.net/qq7366020/article/details/12943345)

//Final   kosaraju判断有向图是否为强联通图
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10100
struct snode{int to,next;
}edge1[MAX*30],edge2[MAX*30],edge3[MAX*30];
int visit1[MAX],In[MAX],To[MAX],pre1[MAX],pre2[MAX],Index1,Index2,k,list[MAX];
int father[MAX];
void Add_edge1(int a,int b)  //建立正向图
{edge1[Index1].to=b,edge1[Index1].next=pre1[a];pre1[a]=Index1++;
}void Add_edge2(int a,int b)  //建立逆向图
{edge2[Index2].to=b,edge2[Index2].next=pre2[a];pre2[a]=Index2++;
}void Kosaraju(int u)     //第一次正向图搜索
{int i,v;for(i=pre1[u];i!=-1;i=edge1[i].next){v=edge1[i].to;if(visit1[v]==0){visit1[v]=1;Kosaraju(v);}}list[k++]=u;
}void DFS(int u,int Father)   //第二次逆向图搜索
{int i,v;visit1[u]=2;father[u]=Father;for(i=pre2[u];i!=-1;i=edge2[i].next){v=edge2[i].to;if(visit1[v]==1)DFS(v,Father);}
}int main()
{int n,m,i,j,a,b,c,pd;while(scanf("%d%d",&n,&m)!=EOF){if(n==0&&m==0)break;Index1=Index2=0;memset(In,0,sizeof(In));memset(pre1,-1,sizeof(pre1));memset(pre2,-1,sizeof(pre2));memset(visit1,0,sizeof(visit1));memset(father,0,sizeof(father));for(i=0;i<m;i++){scanf("%d%d",&a,&b);Add_edge1(a,b);Add_edge2(b,a);}for(i=1,k=0;i<=n;i++){if(!visit1[i]){visit1[i]=1;Kosaraju(i);}}for(j=k-1,c=0;j>=0;j--)    //第二次搜索和第一次搜索顶点的顺序一样{if(visit1[list[j]]==1){DFS(list[j],++c);}}for(i=1,pd=0;i<n;i++)   //有两个联通块就说明不是联通图if(father[i]!=father[i+1])pd=1;if(pd==0)printf("Yes\n");elseprintf("No\n");}return 0;
}

其实这题还是可以用并查集做的AC代码:(https://blog.csdn.net/wyjwyl/article/details/49369085)

#include<cstdio>
#include<cstring>
#define maxn 10000+10
int rec[3][maxn];
int n,m;
void init()
{for(int i=1;i<=2;++i){for(int j=1;j<=n;++j)rec[i][j]=j;}
}
int find(int x,int i)
{return x==rec[i][x]?x:rec[i][x]=find(rec[i][x],i);
}
void merge(int a,int b)
{if(a!=n){int fa=find(a,1);int fb=find(b,1);if(fa!=fb)rec[1][a]=b;//合并到后面的那个元素身上}if(b!=n){int fa=find(a,2);int fb=find(b,2);if(fa!=fb)rec[2][b]=a;//合并到前面的那个元素上}
}
int main()
{int a,b;while(scanf("%d%d",&n,&m)&&(n||m)){int flag=1;init();for(int i=1;i<=m;++i){scanf("%d%d",&a,&b);merge(a,b);}for(int i=1;i<=n;++i){if(find(i,1)!=n||find(i,2)!=n){flag=0;break;}}if(flag)puts("Yes");elseputs("No");}return 0;
}

超时代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int MAXN = 10000 + 5;
const int MAXM = 100000 + 5;
int n,m;
int top,flag;
int head[MAXN];
bool vis[MAXN];
struct Edge {int to,ne;}e[MAXM]; 
void add(int u,int v) {e[++top].to = v;e[top].ne = head[u];head[u] = top;
}
void dfs(int x,int cnt) {if(x == 1 && cnt == n+1) {
//		for(int i = head[x]; i!=-1; i=e[i].ne) {
//			if(e[i].to == 1) {
//				flag =1;break;
//			}
//		}flag=1;return ;}for(int i = head[x]; i!=-1; i=e[i].ne) {if(vis[e[i].to] && e[i].to != 1) continue;vis[e[i].to]=1;dfs(e[i].to,cnt+1);if(flag) return;vis[e[i].to] = 0;}
}
int main()
{int a,b;while(~scanf("%d%d",&n,&m)) {if(n == 0 && m == 0) break;top = flag = 0;memset(head,-1,sizeof head);memset(vis,0,sizeof vis);for(int i = 1; i<=m; i++) {scanf("%d%d",&a,&b);add(a,b);}dfs(1,1);if(flag) puts("Yes");else puts("No");}return 0 ;
}

总结: 这件事情告诉我们一个道理。。。。不带回溯的dfs要比带回溯的dfs快的多的多的多,因为不带回溯的是一遍on,带回溯的是n!

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

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

相关文章

php5.4 curl,PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析

本文实例分析了PHP5.0~5.6 各版本兼容性cURL文件上传功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;最近做的一个需求&#xff0c;要通过PHP调用cURL&#xff0c;以multipart/form-data格式上传文件。踩坑若干&#xff0c;够一篇文章了。重要警告没事不要读PHP的…

【HDU - 1518】Square (经典的dfs + 剪枝)

题干&#xff1a; Given a set of sticks of various lengths, is it possible to join them end-to-end to form a square? Input The first line of input contains N, the number of test cases. Each test case begins with an integer 4 < M < 20, the number …

php发扑克牌,php 扑克牌代码的简单例子

本文分享下&#xff0c;一段可模拟扑克牌玩法的php代码&#xff0c;有需要的朋友参考下。php 扑克牌代码&#xff0c;如下&#xff1a;cut();* www: jbxue.com*/class cards{/**** Declare our deck variable**/private $deck;/**** Constructor.. duh!**/function __construct…

【HDU - 1026 】Ignatius and the Princess I (bfs + 记录路径)

题干&#xff1a; The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166s castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrinth is a N*…

php多线程模拟请求,浅谈php使用curl模拟多线程发送请求

每个PHP文件的执行是单线程的&#xff0c;但是php本身也可以用一些别的技术实现多线程并发比如用php-fpm进程&#xff0c;这里用curl模拟多线程发送请求。php的curl多线程是通过不断调用curl_multi_exec来获取内容&#xff0c;这里举一个demo来模拟一次curl多线程并发操作。//设…

【HDU - 1455】Sticks (dfs + 剪枝)

题干&#xff1a; George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were original…

java找不到符号类socket,编译报错+解决方法:错误: 找不到符号

public class ServerPlainTest { // 包内包外可见public static void main(String[] args) {try {ServerSocket ss new ServerSocket(8189);System.out.println("the server has startuped, waiting for connections.");while (true) { // accept multiple clients …

php hbase thrift,PHP使用Thrift操作Hbase

系统架构图HBase 启动 Thrift服务hbase启动thrift服务// 进入安装的hbase bin目录下// 执行hbase-daemon.sh start thrift2需要注意的是&#xff0c;这里启动的是thrift2服务&#xff0c;如果需要启动thrift服务只需要将thrift2改为thrift就可以了&#xff0c;具体thrift和thri…

【CodeForces - 761D 】Dasha and Very Difficult Problem (构造,思维)

题干&#xff1a; Dasha logged into the system and began to solve problems. One of them is as follows: Given two sequences a and b of length n each you need to write a sequence c of length n, the i-th element of which is calculated as follows: ci  bi -…

php excel下载打不开了,php下载excel无法打开的解决方法

php下载excel文件,1、在下载的过程中不要 输出任何非文件信息&#xff0c;比如 echo log信息。 否则下载后的文件无法打开&#xff0c;提示格式错误或者文件被破坏。2、 输出的excel格式一定要和后缀名保存一直&#xff0c;否也会提示格式错误或者文件被破坏if (file_exists(CA…

【CodeForces - 761B】Dasha and friends (思维,模拟,构造)

题干&#xff1a; Running with barriers on the circle track is very popular in the country where Dasha lives, so no wonder that on her way to classes she saw the following situation: The track is the circle with length L, in distinct points of which there…

php字符串变量,PHP 字符串变量

PHP 字符串变量字符串变量用于存储并处理文本。PHP 中的字符串变量字符串变量用于包含有字符的值。在创建字符串之后&#xff0c;我们就可以对它进行操作了。您可以直接在函数中使用字符串&#xff0c;或者把它存储在变量中。在下面的实例中&#xff0c;我们创建一个名为 txt 的…

【CodeForces - 761C】Dasha and Password (暴力可过,标解dp,字符串,有坑总结)

题干&#xff1a; After overcoming the stairs Dasha came to classes. She needed to write a password to begin her classes. The password is a string of length n which satisfies the following requirements: There is at least one digit in the string,There is a…

php4和php5的区别,什么是PHP 4和PHP 5之间的区别是什么-php是什么文件

&#xff1f;尽管PHP 5是故意设计成兼容尽可能与以前的版本&#xff0c;也有一些显著的变化。 其中的一些变化包括&#xff1a; 一个新的OOP模型基础上&#xff0c;Zend引擎2.0 改进MySQL支持的一个新推广 内置SQLite的原生支持 一个新的错误报告不断&#xff0c; E_STRICT &am…

【HDU - 2717】【POJ - 3278】Catch That Cow (经典bfs,类似dp)

题干&#xff1a; Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farme…

php 向公众号发送消息,微信公众号之主动给用户发送消息功能

前一段时间项目中遇到一个稍微麻烦一点的问题。即客户要求&#xff0c;他在后台编辑好文章后要主动给每个用户都发送消息&#xff0c;并可以让用户点击直接进入文章页面。于是乎&#xff0c;当时脑子一热&#xff0c;想着没什么大的问题&#xff0c;so easy。模板消息不就得了。…

【CodeForces - 764A】Taymyr is calling you (找规律,水题)

题干&#xff1a; Comrade Dujikov is busy choosing artists for Timofeys birthday and is recieving calls from Taymyr from Ilia-alpinist. Ilia-alpinist calls every n minutes, i.e. in minutes n, 2n, 3n and so on. Artists come to the comrade every m minutes, …

ecshop php升级,升级-安装与升级- ECShop帮助

ECShop V2.6.2版本有GBK和UFT-8两种编码格式的程序&#xff0c;而低于ECShop V2.6.0 的版本只有UTF-8 编码的(这些版本包括 ECShop 2.5.1、ECShop 2.5.0、ECShop 2.1.5、ECShop 2.1.2b等)&#xff0c; 这些版本升级到ECShop V2.6.2均可以使用本程序升级。相同版本的升级只需要覆…

【CodeForces - 764B 】Timofey and cubes (模拟)

题干&#xff1a; Young Timofey has a birthday today! He got kit of n cubes as a birthday present from his parents. Every cube has a number ai, which is written on it. Timofey put all the cubes in a row and went to unpack other presents. In this time, Tim…

php页面转发,php如何实现页面路由转发

php实现页面路由转发的方法&#xff1a;首先配置nginx服务器&#xff0c;在【.htaccess】中写上nginx的语法&#xff1b;然后打开根目录的【index.php】&#xff0c;编写文件路由即可。php实现页面路由转发的方法&#xff1a;1、配置nginx服务器nginx服务器不会自动读取.htacce…