可以用下面两个代码
来加速cin 与cout ,这样cin的速度就和sanf差不多了,
注意,这两个代码的头文件是 iostream
并且如果用了这两个,就不要用scanf ,getchar,gets,fgets,fscanf了,
他的作用是关于 iostream和stdio的同步,让c++和c的输入出不在挂钩了(具体原理我也不清楚哈)
还有就是,用“\n”而不是 endl,也可以提高速度。
std::ios::sync_with_stdio(false);
cin.tie(0);
第二个是取消cin与cout的绑定,去掉了也没用。
但是数据量大还是推荐用scanf,
开加速也可能会卡。
#include <bits/stdc++.h> using namespace std; struct Edge { int to, next; }data[10010]; int head[1010], cnt; void addEdge(int from, int to) { data[cnt].to = to; data[cnt].next = head[from]; head[from] = cnt++; } int main(int argc, char **argv) { memset(head, -1, sizeof(head)); int from, to; int vertex, edge; scanf("%d %d", &vertex, &edge); for (int i = 0; i < edge; i++) { scanf("%d %d", &from, &to); addEdge(from, to); } return 0; }
邻接表的代码实现。
01
#include <bits/stdc++.h>
02
03
04
//牛洪凯版。。。。。静态结构体数组,
05
//head不存值通过在数组上往外链接指针链表。
06
//把每个点能够指向的点依次插入。
07
//错误::忘记遍历时忘记了p=p->next
08
09
10
using
namespace
std;
11
struct
code
12
{
13
int
e;
14
code *next;
15
} head[5005],*p,*r;
16
int
main()
17
{
18
int
q,n,i,j,x,y,s;
19
while
(~
scanf
(
"%d"
,&n))
20
{
21
for
(i=0; i<n; i++)
22
head[i].next=NULL;
23
for
(i=0; i<n; i++)
24
{
25
for
(j=0; j<n; j++)
26
{
27
scanf
(
"%d"
,&x);
28
if
(x==1)
29
{
30
p=
new
code;
31
p->e=j;
32
p->next=head[i].next;
33
head[i].next=p;
34
}
35
}
36
}
37
scanf
(
"%d"
,&q);
38
while
(q--)
39
{
40
scanf
(
"%d%d"
,&x,&y);
41
p=head[x].next;
42
s=1;
43
while
(p!=NULL)
44
{
45
if
(p->e==y)
46
{
47
printf
(
"Yes\n"
);
48
s=0;
49
break
;
50
}
51
p=p->next;
52
}
53
if
(s==1)
printf
(
"No\n"
);
54
}
55
}
56
return
0;
57
}
58
数据结构实验之图论四:迷宫探索
Problem Description
Input
连续T组数据输入,每组数据第一行给出三个正整数,分别表示地下迷宫的结点数N(1 < N <= 1000)、边数M(M <= 3000)和起始结点编号S,随后M行对应M条边,每行给出一对正整数,表示一条边相关联的两个顶点的编号。
Output
若可以点亮所有结点的灯,则输出从S开始并以S结束的序列,序列中相邻的顶点一定有边,否则只输出部分点亮的灯的结点序列,最后输出0,表示此迷宫不是连通图。
访问顶点时约定以编号小的结点优先的次序访问,点亮所有可以点亮的灯后,以原路返回的方式回到起点。
Example Input
1 6 8 1 1 2 2 3 3 4 4 5 5 6 6 4 3 6 1 5
Example Output
1 2 3 4 5 6 5 4 3 2 1
01
#include <bits/stdc++.h>
02
03
using
namespace
std;
04
05
int
vis[3105],ma[3105][3105],a[3100];
06
//vis储存点访问状态。。。a[][]点与点之间是否联通。
07
int
num,k,m;
08
//表示点数和边数
09
/*深度优先遍历相当于二叉树中的前序遍历,
10
而且深度优先遍历中运用了递归,从进入迷宫到出迷宫,
11
从起点进入最后又从起点出来。递归的先递归到最后最低端,
12
然后再由最低端递归到最开始的地方,
13
二者类似。所以如果是连通图每个点都被来回两次访问,
14
如果不是连通图那么访问次数就小于2*n-1;
15
(最后一个点访问了一次); 如果是连通图的话,
16
DFS深度优先遍历遍历了每个点两次。
17
迷宫图如果是连通图的话,那么每个灯就路过了两次。*/
18
void
dfs(
int
i)
//深度搜索,从某个点开始 。
19
{
20
int
j;
21
vis[i]=1;
22
a[num++]=i;
23
for
(j=1; j<=k; j++)
//点数从0到存在的点
24
{
25
if
(ma[i][j]==1&&vis[j]==0)
//两个点之间有无向线段。
26
{
27
vis[j]=1;
//标记已经走过。
28
dfs(j);
//深度搜索从j开始。
29
a[num++]=i;
30
}
31
}
32
}
33
int
main()
34
{
35
int
n,i,u,x,y;
36
cin>>n;
37
while
(n--)
38
{
39
cin>>k>>m>>u;
40
memset
(vis,0,
sizeof
(vis));
41
memset
(ma,0,
sizeof
(ma));
42
for
(i=0; i<m; i++)
43
{
44
cin>>x>>y;
45
ma[x][y]=ma[y][x]=1;
46
}
47
num=0;
48
dfs(u);
49
for
(i=0;i<num;i++)
50
{
51
if
(i==0)
52
cout<<a[i];
53
else
54
cout<<
" "
<<a[i];
55
}
56
if
(num!=2*k-1)
57
cout<<
" 0"
;
58
cout<<endl;
59
}
60
return
0;
61
}
数据结构实验之图论四:迷宫探索
Time Limit: 1000MS Memory Limit: 65536KBProblem Description
有一个地下迷宫,它的通道都是直的,而通道所有交叉点(包括通道的端点)上都有一盏灯和一个开关;请问如何从某个起点开始在迷宫中点亮所有的灯并回到起点?Input
连续T组数据输入,每组数据第一行给出三个正整数,分别表示地下迷宫的结点数N(1 < N <= 1000)、边数M(M <= 3000)和起始结点编号S,随后M行对应M条边,每行给出一对正整数,表示一条边相关联的两个顶点的编号。
Output
若可以点亮所有结点的灯,则输出从S开始并以S结束的序列,序列中相邻的顶点一定有边,否则只输出部分点亮的灯的结点序列,最后输出0,表示此迷宫不是连通图。 访问顶点时约定以编号小的结点优先的次序访问,点亮所有可以点亮的灯后,以原路返回的方式回到起点。
Example Input
1 6 8 1 1 2 2 3 3 4 4 5 5 6 6 4 3 6 1 5Example Output
1 2 3 4 5 6 5 4 3 2 1
01
#include <bits/stdc++.h>
02
03
using
namespace
std;
04
05
int
vis[3105],ma[3105][3105],a[3100];
06
//vis储存点访问状态。。。a[][]点与点之间是否联通。
07
int
num,k,m;
08
//表示点数和边数
09
/*深度优先遍历相当于二叉树中的前序遍历,
10
而且深度优先遍历中运用了递归,从进入迷宫到出迷宫,
11
从起点进入最后又从起点出来。递归的先递归到最后最低端,
12
然后再由最低端递归到最开始的地方,
13
二者类似。所以如果是连通图每个点都被来回两次访问,
14
如果不是连通图那么访问次数就小于2*n-1;
15
(最后一个点访问了一次); 如果是连通图的话,
16
DFS深度优先遍历遍历了每个点两次。
17
迷宫图如果是连通图的话,那么每个灯就路过了两次。*/
18
void
dfs(
int
i)
//深度搜索,从某个点开始 。
19
{
20
int
j;
21
vis[i]=1;
22
a[num++]=i;
23
for
(j=1; j<=k; j++)
//点数从0到存在的点
24
{
25
if
(ma[i][j]==1&&vis[j]==0)
//两个点之间有无向线段。
26
{
27
vis[j]=1;
//标记已经走过。
28
dfs(j);
//深度搜索从j开始。
29
a[num++]=i;//不同于深度遍历之处在于这里,在递归结束后一层一层的往回返回并且进入数组中。
30
}
31
}
32
}
33
int
main()
34
{
35
int
n,i,u,x,y;
36
cin>>n;
37
while
(n--)
38
{
39
cin>>k>>m>>u;
40
memset
(vis,0,
sizeof
(vis));
41
memset
(ma,0,
sizeof
(ma));
42
for
(i=0; i<m; i++)
43
{
44
cin>>x>>y;
45
ma[x][y]=ma[y][x]=1;
46
}
47
num=0;
48
dfs(u);
49
for
(i=0;i<num;i++)
50
{
51
if
(i==0)
52
cout<<a[i];
53
else
54
cout<<
" "
<<a[i];
55
}
56
if
(num!=2*k-1)
57
cout<<
" 0"
;
58
cout<<endl;
59
}
60
return
0;
61
}
数据结构实验之图论二:基于邻接表的广度优先搜索遍历
Time Limit: 1000MS Memory Limit: 65536KBProblem Description
给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列。(同一个结点的同层邻接点,节点编号小的优先遍历)Input
输入第一行为整数n(0< n <100),表示数据的组数。 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),表示有m条边,k个顶点,t为遍历的起始顶点。 下面的m行,每行是空格隔开的两个整数u,v,表示一条连接u,v顶点的无向边。Output
输出有n行,对应n组输出,每行为用空格隔开的k个整数,对应一组数据,表示BFS的遍历结果。Example Input
1 6 7 0 0 3 0 4 1 4 1 5 2 3 2 4 3 5Example Output
0 3 4 2 5 1
01
#include <bits/stdc++.h>
02
#include<stdio.h>
03
using
namespace
std;
04
int
b[11],que[11],a[10][10];
05
//队列先进先出。
06
07
void
bfs(
int
r,
int
len )
08
{
09
int
i=0,vis[11];
//标记是否走过。
10
memset
(vis,0,
sizeof
(vis));
//初始化假设所有的点都未走过。
11
int
s=0,e=0;
12
vis[r]=1;
13
//e入队s出对。并且标记起始顶点已走过。
14
que[e++]=r;
15
b[i++]=r;
16
//b为输出数组。
17
while
(s<e)
18
{
19
for
(
int
j=0;j<len;j++)
20
{
21
if
(a[que[s]][j]==1&&!vis[j])
22
{
23
que[e++]=j;
24
vis[j]=1;
25
b[i++]=j;
26
}
27
}
28
s++;
29
}
30
}
31
int
main()
32
{
33
int
n,m,t,k,i,j;
34
scanf
(
"%d"
,&n);
35
while
(n--)
36
{
37
scanf
(
"%d%d%d"
,&k,&m,&t);
38
memset
(a,0,
sizeof
(a));
39
while
(m--)
40
{
41
scanf
(
"%d%d"
,&i,&j);
42
a[i][j]=a[j][i]=1;
43
}
44
bfs(t,k);
45
for
(i=0;i<k;i++)
46
{
47
cout<<b[i];
48
(i==k-1?cout<<endl:cout<<
" "
);
49
}
50
}
51
return
0;
52
}
Catch That Cow
Time Limit: 2000MS Memory Limit: 65536KBProblem Description
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. Farmer John has two modes of transportation: walking and teleporting. * Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute * Teleporting: FJ can move from any point X to the point 2 × X in a single minute. If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?Input
Line 1: Two space-separated integers: N and KOutput
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.Example Input
5 17Example Output
4
题意:FJ要抓奶牛。
开始输入N(FJ的位置)K(奶牛的位置)。
FJ有三种移动方法:1、向前走一步,耗时一分钟。
2、向后走一步,耗时一分钟。
3、向前移动到当前位置的两倍N*2,耗时一分钟。
问FJ抓到奶牛的最少时间。PS:奶牛是不会动的。
思路:1、如果FJ不在奶牛后面,那么他只有一步步往后移动到奶牛位置了,即N>=K时,输出N-K即可。
2、否则bfs+队列查找(具体见下面的分析&&代码区)
相关算法:
1、STL中的队列。(PS:周四才在数据结构上了解bfs的真正思想,惭愧啊!)
需要的头文件:STL是C++中的 #include<iostream>
using namespace std;
queue队列容器的头文件 #include<queue>
queue队列的相关用法:先进先出(FIFO)
入队push() //即插入元素
出队pop() //即删除元素
front() //读取队首元素
back() //读取队尾元素
empty() //判断队列是否为空
size() //读取队列当前元素的个数
2、bfs思想:节点进行广度优先搜索的顺序。
搜索实现方法(非递归):
算法思想:1.设置一个队列Q,从顶点出发,遍历该顶点后让其进队;
2.出队一个顶点元素,求该顶点的所有邻接点(对应于此题即FJ的三种走法),
对于没有遍历过的邻接点遍历之,并 让其进队;
3.若队空停止,队不空时继续第2步。
深度优先搜索练习之神奇的矩环
Time Limit: 1000MS Memory Limit: 65536KBProblem Description
小鑫的女朋友被魔王抢走了! 魔王留给小鑫一张n*m大的表,上面有各种各样的颜色,用A-Z这26个字母来表示。魔王留给他一个任务,如果小鑫可以在这张表中找出任意一个长度大于1的环,并且这个环的颜色是相同的,魔王就把小鑫的女朋友还给他。为了从魔王手中夺回他的女朋友,小鑫请你帮忙,你能帮帮他吗?Input
多组输入。 每组的第一行有两个整数n,m。代表表的大小。 接下来是由A-Z的一些字母所构成的n行m列的表。 1<=n,m<=200Output
如果可以救回他的女朋友,输出Yes,否则输出NoExample Input
4 7 ABCBBAA BCBCBCB AABBCCA ACCCBBB 10 3 AAC ABB BBA AAC CBC CCA CBB CCA CCB BAAExample Output
No Yes
#include <bits/stdc++.h>
02
using
namespace
std;
03
char
dap[205][205];
04
int
vis[201][201];
05
int
n,m,flag;
06
int
go[4][2]= {{1,0},{0,1},{0,-1},{-1,0}};
07
void
dfs(
int
x,
int
y,
int
x1,
int
y1)
08
{
09
vis[x][y]=1;
//每次进来DFS都会标记。//
10
for
(
int
t=0; t<4; t++)
11
{
12
int
i=x+go[t][0];
13
int
j=y+go[t][1];
14
if
(i>=0&&i<n&&j>=0&&j<m&&dap[i][j]==dap[x][y])
15
{
16
if
(!vis[i][j])
//没被标记就继续走直到走不动或者发现环。
17
dfs(i,j,x,y);
//递归调用。
18
else
if
(i!=x1&&j!=y1)
//当前节点的上一节点不是父亲节点并已经被访问过那么就构成了环,
19
{
20
flag=1;
21
return
;
22
}
23
}
24
}
25
}
26
int
main()
27
{
28
std::ios::sync_with_stdio(
false
);
29
while
(cin>>n>>m)
30
{
31
flag=0;
32
memset
(vis,0,
sizeof
(vis));
33
for
(
int
i=0;i<n;i++)
34
cin>>dap[i];
35
for
(
int
i=0;i<n;i++)
36
{
37
for
(
int
j=0;j<m;j++)
38
{
39
if
(!vis[i][j])
40
{
41
dfs(i,j,i,j);
//只要没被标记过就可以从这里开始去寻找环,
42
if
(flag)
43
break
;
44
}
45
}
46
47
if
(flag)
48
break
;
49
}
50
if
(flag)
51
cout<<
"Yes"
<<endl;
52
else
53
cout<<
"No"
<<endl;
54
}
55
return
0;
56
}