DFS
#include<iostream>
#define MAXSIZE 20
using namespace std;
int map[MAXSIZE][MAXSIZE]={0};
int point[MAXSIZE];
int visited[MAXSIZE]={0};
void DFS(int vernum,int v){
cout<<point[v];
visited[v]=1;
for(int i=0;i<vernum;i++){
if(visited[i]==0&&map[v][i]==1){
DFS(vernum,i);
}
}
}
int main()
{
int edge_num,ver_num;
cin>>ver_num>>edge_num;
for(int i=0;i<ver_num;i++){
int x;
cin>>x;
point[i]=x;
}
for(int i=0;i<edge_num;i++){
int x,y;
cin>>x>>y;
map[x-1][y-1]=map[y-1][x-1]=1;
}
DFS(ver_num,0);
}
测试数据:
5 6
0 1 2 3 4
1 2
1 4
2 3
2 5
3 4
3 5
结果:0 1 2 3 4
BFS
#include<iostream>
#include<queue>
#define MAXSIZE 20
using namespace std;
int map[MAXSIZE][MAXSIZE]={0};
int point[MAXSIZE]={0};
int visited[MAXSIZE]={0};
queue<int>q;
void BFS(int ver_num,int v){
cout<<point[v];
visited[v]=1;
for(int i=0;i<ver_num;i++){
if(visited[i]==0&&map[v][i]==0){
q.push(point[i]);
}
}
while(!q.empty()){
int q_front=q.front();
cout<<q_front;
q.pop();
for(int i=0;i<ver_num;i++){
if(visited[i]==0&&map[q_front][i]==0){
q.push(point[i]);
}
}
}
}
int main()
{
int edge_num,ver_num;
cin>>ver_num>>edge_num;
for(int i=0;i<ver_num;i++){
int x;
cin>>x;
point[i]=x;
}
for(int i=0;i<edge_num;i++){
int x,y;
cin>>x>>y;
map[x-1][y-1]=map[y-1][x-1]=1;
}
BFS(ver_num,0);
}
测试数据同上
结果:0 1 3 2 4
单源最短路径
#include<iostream>
using namespace std;
int g[20][20];
int dist[20];//用来保存源点到各个点的最短路径
int visited[20];
int m, n;
void Dijkstra() {
dist[0] = 0;//代表源点到自身的距离是0
for (;;) {
int min = INT_MAX;
int v;
for (int i = 0;i < m;i++) {
if (visited[i] == 0 && min > dist[i]) {
min = dist[i];
v = i;
}
}
if (min == INT_MAX) break;
visited[v] = 1;
for (int w = 0;w < m;w++) {
if (visited[w] == 0 && g[v][w] != INT_MAX && dist[w] > dist[v] + g[v][w])
dist[w] = dist[v] + g[v][w];//直接到这个点的距离是否比我先到这个点再到目的点大,如果大则更新
}
}
}
int main()
{
for (int i = 0;i < 20;i++)
{
dist[i] = INT_MAX;
for (int j = 0;j < 20;j++)
{
g[i][j] = INT_MAX;
}
}
cin >> m >> n;
for (int i = 0;i < n;i++)
{
int x, y, z;
cin >> x >> y >> z;
g[x - 1][y - 1] = z;
}
Dijkstra();
for (int i = 0;i < m;i++)
cout << dist[i]<<" ";
}
最小生成树
prim
#include<iostream>
using namespace std;
int graph[20][20];
int visited[20];
int dist[20];
int sum = 0;
int n, m;
int Prim()
{
dist[0] = 0;//源点到自身的距离
int i;
for (i = 0;i < n;i++)
{
int min = INT_MAX,v;
for (int j = 0;j < n;j++)
{
if (min > dist[j] && visited[j] == 0)
{/*第一次循环保存的点肯定是源点,然后在第二个个循环中把源点能到的点的权值都加入
到dist中,那么这个dist中的值就代码能到这个点(dist的下标)的最小距离,它是在第二个循环中不断更新的*/
min = dist[j];//找到当前权最小的且未被访问过的点
v = j;//保存当前访问的点
}
}
if (min == INT_MAX)
break;
visited[v] = 1;
sum += dist[v];//把当前选中点的权值加上
for (int w = 0;w < n;w++)
{
if (visited[w] == 0 && graph[v][w] != INT_MAX && dist[w] > graph[v][w])
/* 如现在源点1到点2和点3的权值分别为6,那么访问源点1的时候
dist[2]=6,dist[3]=1,那么源点访问结束,根据第一个循环访问节点3,点3到点2的权值
比源点1到点2短,也就是dist[w]>graph[3][2],那么这里就会更新dist[2]*/
dist[w] = graph[v][w];
}
}
return i==n;//判断是否可以生成树
}
int main()
{
for (int i = 0;i < 20;i++)
{
visited[i] = 0;
dist[i] = INT_MAX;
for (int j = 0;j < 20;j++)
graph[i][j] = INT_MAX;
}
cin >> n >> m;
for (int i = 0;i < m;i++)
{
int x, y, z;
cin >> x >> y >> z;
graph[x - 1][y - 1] = graph[y - 1][x - 1] = z;
}
if (Prim())
{
cout << sum;
}
}
kruskal
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int G[20][20];
int sum = 0;
struct Edge
{
int src;
int dest;
int weight;
Edge(int s, int d, int w) :src(s), dest(d), weight(w) {}
bool operator<(const Edge& other)
{
return this->weight < other.weight;
}
};
vector<Edge> Paths;
int node[20] = { 0 };
void Initunion(int n)
{
for (int i = 1;i <= n;i++)
node[i] = i;
}
int Find(int x)
{
if (x == node[x])
return node[x];
else return Find(node[x]);
}
void unite(int x, int y)
{
x = Find(x);
y = Find(y);
if (x == y)
return;
else
node[x] = y;
}
bool Same(int x, int y)
{
return Find(x) == Find(y);
}
void Init(int m)
{
for (int i = 0;i < m;i++)
{
int x, y, z;
cin >> x >> y >> z;
G[x][y] = G[y][x] = z;
Edge e(x, y, z);
Paths.push_back(e);
}
}
void Kruskal(int n)
{
for (int i = 1;i < n;)
{
auto iter = min_element(Paths.begin(), Paths.end());
int x = iter->src;
int y = iter->dest;
if (Same(x, y) == false)
{
sum += iter->weight;
unite(x, y);
i++;
}
Paths.erase(iter);
}
}
int main()
{
int n, m;
cin >> n >> m;
Init(m);
Initunion(n);
Kruskal(n);
cout << sum;
}
拓扑排序
#include<iostream>
#include<stack>
using namespace std;
int graph[20][20];
int dist[20];
int n, m;
stack<int>s;
void sum()
{
for (int i = 0;i < n;i++)
{
for (int j = 0;j < n;j++)
{
dist[i] += graph[j][i];
}
}
}
void Topo()
{
for (int i = 0;i < n;i++)
if (dist[i] == 0)
s.push(i);
while (!s.empty())
{
int s_top = s.top();
s.pop();
cout << s_top;
for (int i = 0;i < n;i++)
{
if (graph[s_top][i] == 1)
{
dist[i]--;
if (dist[i] == 0)
s.push(i);
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0;i < m;i++)
{
int x, y;
cin >> x >> y;
graph[x - 1][y - 1] = 1;
}
sum();
Topo();
}
floyd
#include<iostream>
using namespace std;
int g[20][20];
int dist[20][20];
int n, m;
void Floyd()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for (int k = 0;k < n;k++)
{
if (g[i][k] != INT_MAX && g[j][i] + g[i][k] < g[j][k])
dist[i][j] = g[i][j] + g[i][k];
}
}
int main()
{
for (int i = 0;i < 20;i++)
{
for (int j = 0;j < 20;j++)
{
g[i][j] = INT_MAX;
}
}
cin >> n >> m;
for (int i = 0;i < m;i++)
{
int a, b, c;
cin >> a >> b >> c;
g[a - 1][b - 1] = c;
}
Floyd();
}
图的连通分量
#include<iostream>
using namespace std;
int g[20][20];
int visited[20];
int n, m;
int coun = 0;
void DFS(int v)
{
visited[v] = 1;
for (int i = 0;i < n;i++)
{
if (visited[i] == 0 && g[v][i] == 1)
DFS(i);
}
}
void Conet()
{
for (int i = 0;i < n;i++)
{
for (int j = 0;j < n;j++)
{
if (visited[i] == 0 && g[i][j] == 1)
{
DFS(i);
coun++;
}
}
}
}
int main()
{
cin >> n >> m;
for (int i = 0;i < m;i++)
{
int x, y;
cin >> x >> y;
g[x - 1][y - 1] = g[y - 1][x - 1] = 1;
}
Conet();
cout << coun;
}
关键路径
#include<iostream>
using namespace std;
#define MAX 20
int g[MAX][MAX];
int indegree[MAX] = { 0 };
int outdegree[MAX] = { 0 };
int visit[MAX] = { 0 };
int early[MAX] = { 0 };
int later[MAX] = { 1000 };
int n, m;
void Creat()
{
for (int i = 0;i < m;i++)
{
int x, y, z;
cin >> x >> y >> z;
g[x - 1][y - 1] = z;
indegree[y - 1]++;
outdegree[x - 1]++;
}
}
void AOE_early()
{
for (int i = 0;i < n;i++)
{
if (visit[i] == 0 && indegree[i] == 0)
{
visit[i] = 1;
for (int j = 0;j < n;j++)
{
if (g[i][j] != 0)
{
indegree[j]--;
if (early[j] < early[i] + g[i][j])
early[j] = early[i] + g[i][j];
}
}
}
i = 0;
continue;
}
}
void AOE_later()
{
for (int i = 0;i < n;i++)
{
visit[i] = 0;
later[i] = INT_MAX;
}
later[n - 1] = early[n - 1];
later[0] = early[0];
for (int i = n-1;i >0;i--)
{
if (visit[i]==0&&outdegree[i] < INT_MAX)
{
visit[i] = 1;
for (int j = n-1;j >0;j--)
{
if (g[j][i] != 0)
{
outdegree[j]--;
if (later[j] > later[i] - g[j][i])
later[j] = later[i] - g[j][i];
}
}
}
i = 0;
continue;
}
}
int main()
{
cin >> n >> m;
Creat();
AOE_early();
AOE_later();
int k;
cin >> k;
for (int i = 0;i < k;i++)
{
int a;
cin >> a;
cout << early[a - 1] << " " << later[a - 1];
cout << endl;
}
}