图 各个算法实现

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;
 }
}
发布了23 篇原创文章 · 获赞 15 · 访问量 5783

猜你喜欢

转载自blog.csdn.net/qq_42193790/article/details/104170773