dfs
题目: 排列数字
题意:就是让你输出全排列。
思路:可以用dfs去搜索。
代码:数组标记
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
int pri[maxn], n, vis[maxn];
void dfs(int step){
if(step == n){
for(int i = 0; i < n; i++){
if(i != 0)cout<<" ";
cout<<pri[i];
}
cout<<endl;
return;
}
for(int i = 1; i <= n; i++){
if(!vis[i]){
vis[i] = 1;//标记
pri[step] = i;//记录
dfs(step+1);
vis[i] = 0;//恢复现场
pri[step] = 0;
}
}
}
int main(){
cin>>n;
dfs(0);
return 0;
}
通过位运算标记:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
int pri[maxn], n, vis = 0;
void dfs(int step){
if(step == n){
for(int i = 0; i < n; i++){
if(i != 0)cout<<" ";
cout<<pri[i];
}
cout<<endl;
return;
}
// cout<<step<<endl;
for(int i = 1; i <= n; i++){
if((vis & (1<<i)) == 0){
vis += 1<<i;
//cout<<vis<<endl;
pri[step] = i;
dfs(step+1);
vis -= 1<<i;
pri[step] = 0;
}
}
}
int main(){
cin>>n;
vis = 0;
dfs(0);
return 0;
}
题目:n-皇后问题
题意:在同一行或者同一列,不能放置Q,把所有的结果输出来。
思路:以行为参数,去搜索列。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10;
int c[maxn*2], r[maxn*2], vis[maxn];
int n;
char mp[maxn][maxn];
void dfs(int u){
if(u == n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)cout<<mp[i][j];
cout<<endl;
}
cout<<endl;
return;
}
for(int i = 0; i < n; i++){
if(!vis[i] && !c[n-u+i] && !r[u+i]){ //行c: y = x + b -> b = y-x,由于可能是负的所以加一个n,列r:y = x - b -> b = y+x,
vis[i] = 1;
c[n-u+i] = 1;
r[u+i] = 1;
mp[u][i] = 'Q';
dfs(u+1);
vis[i] = 0;//恢复现场
c[n-u+i] = 0;
r[u+i] = 0;
mp[u][i] = '.';
}
}
}
int main(){
cin>>n;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)mp[i][j] = '.';
}
dfs(0);
return 0;
}
bfs
题目:走迷宫
题意:给你一个图0代表可以走, 1代表不可以走,问你从(1, 1)到(n, m)的最短距离。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100;
int n, m;
int dx[4] = {0,0, -1, 1};
int dy[4] = {1, -1, 0, 0};
int mp[maxn][maxn], vis[maxn][maxn];
typedef pair<int, int> PII;
PII tmp;
void bfs(){
queue<PII>q;
vis[1][1] = 0;
q.push({1, 1});
while(q.size()){
PII tmp = q.front();
q.pop();
//cout<<tmp.first<<" "<<tmp.second<<endl;
for(int i = 0; i < 4; i++){
int xx, yy;
xx = tmp.first + dx[i];
yy = tmp.second + dy[i];
if(xx >= 1 && xx <= n && yy >= 1 & yy <= m && !mp[xx][yy] && vis[xx][yy] == -1){
q.push({xx, yy});
vis[xx][yy] = vis[tmp.first][tmp.second] + 1;
//if(xx == n && yy == m)break;
}
}
}
}
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
cin>>mp[i][j];
}
}
memset(vis, -1, sizeof vis);
bfs();
cout<<vis[n][m]<<endl;
return 0;
}
题目:图中点的层次
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int h[maxn], to[maxn], nex[maxn], tot = 0;
void add(int u, int v){
to[tot] = v;
nex[tot] = h[u];
h[u] = tot++;
}
int n, m, vis[maxn];
int bfs(){
memset(vis, -1, sizeof vis);
vis[1] = 0;
queue<int>q;
q.push(1);
while(q.size()){
int tmp = q.front();
q.pop();
for(int i = h[tmp]; ~i; i = nex[i]){
int j = to[i];
if(vis[j] == -1){
vis[j] = vis[tmp] + 1;
q.push(j);
if(j == n)break;
}
}
}
return vis[n];
}
int main(){
cin>>n>>m;
int a, b;
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++){
cin>>a>>b;
add(a, b);
}
cout<<bfs()<<endl;
return 0;
}
拓扑排序
题目:有向图的拓扑序列
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int h[maxn], to[maxn], nex[maxn], degree[maxn], tot = 0;
int n, m;
vector<int>v;
void add(int u, int v){
to[tot] = v;
nex[tot] = h[u];
h[u] = tot++;
}
int TopSort(){
queue<int>q;
for(int i = 1; i <= n; i++){
if(!degree[i])q.push(i);//入度为0的点
}
int cnt = 0;
while(q.size()){
int tmp = q.front();
//cout<<tmp<<endl;
cnt++;
q.pop();
v.push_back(tmp);
for(int i = h[tmp]; ~i; i = nex[i]){
int j = to[i];
degree[j]--;
if(!degree[j])q.push(j);
}
}
if(cnt < n)return -1;//代表产生环
return 1;
}
int main(){
cin>>n>>m;
int a, b;
memset(h, -1, sizeof h);
for(int i = 1; i <= m; i++){
cin>>a>>b;
add(a, b);
degree[b]++;//统计入度
}
if(TopSort() == -1)cout<<-1<<endl;
else{ for(int i = 0; i < n; i++){
cout<<v[i]<<" ";
}
puts("");
}
return 0;
}