1.DFS,BFS
#include <iostream>
using namespace std;
const int N =10;
int n;
int path[N];
bool st[N];
void dfs(int u)
{
if(u == n)
{
for(int i = 0;i<n;i++) printf("%d ",path[i]);
puts("");
return;
}
for(int i = 1;i<=n;i++)
{
if(!st[i])
{
path[u] = i;
st[i] = true;
dfs(u+1);
st[i] = false;
}
}
}
int main()
{
cin >> n;
dfs(0);
return 0;
}
n-皇后 :eg:1
#include <iostream>
using namespace std;
const int N = 20;
int n;
char g[N][N];
int col[N],dg[N],udg[N];
void dfs(int u)
{
if(u == n)
{
for(int i = 0;i<n;i++) puts(g[i]);
puts("");
return;
}
for(int i = 0;i < n; i++)
{
if(!col[i] && !dg[u+i] && !udg[n-u+i])
{
g[u][i] = 'Q';
col[i] = dg[u+i] = udg[n-u+i] = true;
dfs(u+1);
col[i] = dg[u+i] = udg[n-u+i] = false;
g[u][i] = '.';
}
}
}
int main()
{
cin >> n;
for(int i = 0;i < n;i++)
for(int j = 0;j<n;j++)
g[i][j] = '.';
dfs(0);
return 0;
}
eg2:
#include <iostream>
using namespace std;
const int N = 20;
int n;
char g[N][N];
bool row[N],col[N],dg[N],udg[N];
void dfs(int x,int y,int s)
{
if(y == n) y = 0,x++;
if(x == n)
{
if(s == n)
{
for(int i = 0;i < n;i++) puts(g[i]);
}
return;
}
//不放皇后
dfs(x,y+1,s);
//放皇后
if(!row[x] && !col[y] && !dg[x+y] && !udg[x-y+n])
{
g[x][y] = 'Q';
row[x] = col[y] = dg[x+y] = udg[x-y+n] = true;
dfs(x,y+1,s+1);
row[x] = col[y] = dg[x+y] = udg[x-y+n] = false;
g[x][y] = '.';
}
}
int main()
{
cin >> n;
for(int i = 0;i<n;i++)
for(int j = 0;j < n;j++)
g[i][j] = '.';
dfs(0,0,0);
return 0;
}
广搜:
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
const int N = 110;
int n,m;
int g[N][N];
int d[N][N];
PII q[N * N],Prev[N][N];
int bfs()
{
int hh = 0,tt = 0;
q[0] = {0,0};
memset(d,-1,sizeof d);
d[0][0] = 0;
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};
while(hh <= tt)
{
auto t = q[ hh++];
for(int i = 0;i < 4;i++)
{
int x = t.first + dx[i],y = t.second + dy[i];
if(x>=0&& x<n && y >= 0 && y<m && g[x][y] == 0 && d[x][y] == -1)
{
d[x][y] = d[t.first][t.second] + 1;
Prev[x][y] = t;
q[ ++tt] = {x,y};
}
}
}
int x = n-1,y = m-1;
while(x||y)
{
cout << x << ' ' << y << endl;
auto t = Prev[x][y];
x= t.first,y = t.second;
}
return d[n-1][m-1];
}
int main()
{
cin >> n >> m;
for(int i = 0;i < n;i ++)
{
for(int j = 0;j<m;j++)
cin >> g[i][j];
}
cout << bfs() <<endl;
}
2.树与图
eg:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010,M=N*2;
int n;
int h[N],e[M],ne[M],idx;
int ans = N;
bool st[N];
void add(int a,int b)
{
e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}
//以u为根的子树中的点的数量
int dfs(int u)
{
st[u] = true;//标记一下,被搜过了
int sum = 1,res = 0;
for(int i = h[u];i != -1;i = ne[i])
{
int j = e[i];
if(!st[j])
{
int s = dfs(j);
res = max(res,s);
sum += s;
}
}
res = max(res,n - sum);
ans = min(ans,res);
return sum;
}
int main()
{
cin >>n;
memset(h,-1,sizeof h);
for(int i = 0;i < n-1;i++)
{
int a,b;
cin >> a >> b;
add(a,b),add(b,a);
}
dfs(1);
cout << ans << endl;
return 0;
}
宽搜
eg:
**#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,m;
int h[N],e[N],ne[N],idx;
int d[N],q[N];
void add(int a,int b)
{
e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}
int bfs()
{
int hh = 0,tt = 0;
q[0] = 1;
memset(d,-1,sizeof d);
d[1] = 0;
while(hh <= tt)
{
int t = q[hh++];
for(int i = h[t];i!=-1;i = ne[i])
{
int j = e[i];
if(d[j] == -1)
{
d[j] = d[t] + 1;
q[++tt] = j;
}
}
}
return d[n];
}
int main()
{
cin >> n >> m;
memset(h,-1,sizeof h);
for(int i = 0;i<m;i++)
{
int a,b;
cin >> a >> b;
add(a,b);
}
cout << bfs() << endl;
return 0;
}
**
有向无环图-》拓扑图
eg:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int n,m;
int h[N],e[N],ne[N],idx;
int q[N],d[N];
void add(int a,int b)
{
e[idx] = b,ne[idx] = h[a],h[a] = idx++;
}
bool topsort()
{
int hh = 0,tt=-1;
for(int i = 1;i<=n;i++)
{
if(!d[i])
q[++tt]= i;
}
while(hh<=tt)
{
int t = q[hh++];
for(int i = h[t];i!=-1;i=ne[i])
{
int j = e[i];
d[j] --;
if(d[j] == 0) q[++tt]=j;
}
}
return tt = n-1;
}
int main()
{
cin >>n >> m;
memset(h,-1,sizeof h);
for(int i = 0;i<m;i++)
{
int a,b;
cin >> a>> b;
add(a,b);
d[b]++;
}
if(topsort())
{
for(int i= 0;i<n;i++) printf("%d ",q[i]);
puts("");
}
else puts("-1");
}
3.最短路
朴素版dijkstra
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510;
int n,m;
int g[N][N];
int dist[N];
bool st[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1] = 0;
for(int i = 0;i < n;i++)
{
int t = -1;
for(int j = 1;j<=n;j++)
{
if(!st[j] && (t == -1||dist[t] > dist[j])) //从st[j] = false的点中找到dist最小的点
t=j;
}
st[t] = true;
for(int j = 1;j<=n;j++)
dist[j] = min(dist[j],dist[t] + g[t][j]);
}
if(dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
scanf("%d%d",&n,&m);
memset(g,0x3f,sizeof g);
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b] = min(g[a][b],c);
}
int t = dijkstra();
printf("%d\n",t);
return 0;
}
堆优化版的dijkstra
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int,int> PII;
const int N = 100010;
int n,m;
int h[N],w[N],e[N],ne[N],idx;
int dist[N];
bool st[N];
void add(int a,int b,int c)
{
e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
}
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1] = 0;
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,1});
while(heap.size())
{
auto t = heap.top();
heap.pop();
int ver = t.second,distance = t.first;
if(st[ver]) continue;
for(int i = h[ver];i!=-1;i=ne[i])
{
int j = e[i];
if(dist[j]>distance + w[i])
{
dist[j] = distance +w[i];
heap.push({dist[j],j});
}
}
}
if(dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
int main()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int t = dijkstra();
printf("%d\n",t);
return 0;
}
bellman-Ford算法
图中可以有负权,但不能有负圈(圈中弧或边的权值之和小于0)
eg: