Graph Theory Algorithms Template Arrangement and Thoughts Continuously Update Absolute Quality

DFS

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio> 
 4 using namespace std;
 5 queue<int>q;
 6 int map[1001][1001];
 7 int vis[1001];
 8 int n,m;
 9 void bfs(int p)
10 {
11     q.push(p);
12     vis[p]=1;
13     printf("%c-->",char(q.front()+64));
14     while(q.size()!=0)
15     {    
16         int k=q.front();
17         q.pop();
18         for(int i=1;i<=n;i++)
19         {
20             
21             if(vis[i]==0&&map[k][i]==1)
22             {
23                 printf("%c-->",char(i+64));
24                 //q.pop();
25                 q.push(i);
26                 vis[i]=1;
27             }
28         }
29     }
30 }
31 int main()
32 {
33     
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=m;i++)
36     {
37         char x,y;
38         //scanf("\n%d %d",&x,&y);
39         cin>>x>>y;
40         x=x-64;
41         y=y-64;
42         map[x][y]=map[y][x]=1;
43     }
44     bfs(1);
45     return 0;
46 }
DFS

BFS

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstdio> 
 4 using namespace std;
 5 queue<int>q;
 6 int map[1001][1001];
 7 int vis[1001];
 8 int n,m;
 9 void bfs(int p)
10 {
11     q.push(p);
12     vis[p]=1;
13     printf("%c-->",char(q.front()+64));
14     while(q.size()!=0)
15     {    
16         int k=q.front();
17         q.pop();
18         for(int i=1;i<=n;i++)
19         {
20             
21             if(vis[i]==0&&map[k][i]==1)
22             {
23                 printf("%c-->",char(i+64));
24                 //q.pop();
25                 q.push(i);
26                 vis[i]=1;
27             }
28         }
29     }
30 }
31 int main()
32 {
33     
34     scanf("%d%d",&n,&m);
35     for(int i=1;i<=m;i++)
36     {
37         char x,y;
38         //scanf("\n%d %d",&x,&y);
39         cin>>x>>y;
40         x=x-64;
41         y=y-64;
42         map[x][y]=map[y][x]=1;
43     }
44     bfs(1);
45     return 0;
46 }
BFS

Flyoed

Idea: Three-tier cyclic traversal of intermediate nodes

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int a[101][101];
 6 int pass[101][101];
 7 int main()
 8 {
 9     memset(a,999999,sizeof(a));
10     int n,m;
11     scanf("%d%d",&n,&m);
12     for(int i=1;i<=m;i++)
13     {
14         int x,y,zhi;
15         scanf("%d%d%d",&x,&y,&zhi);
16         a[x][y]=zhi;
17         a[y][x]=zhi;
18     }
19     for(int k=1;k<=n;k++)
20     {
21         for(int i=1;i<=n;i++)
22         {
23             for(int j=1;j<=n;j++)
24             {
25                 if(a[i][j]>a[i][k]+a[k][j])
26                 {
27                     a[i][j]=a[i][k]+a[k][j];
28                     pass[i][j]=k;
29                 }
30             }
31         }
32     }
33     printf("%d %d\n",a[1][4],a[2][6]);
34     printf("%d %d\n",pass[1][4],pass[2][6]);
35     return 0;
36 }
Flyoed

Dijkstra

Main Idea: Find the nearest point at a time to update the distance to other points.

Ideas:

1. A dis array record pre cursor is needed to record the shortest path from the required point to the other point.

2. (1) Initialization: dis []= dis [starting point] = 0 pre [starting point] = 0

(2) < 1 > for (int i = 1; i < = total number of vertices; i +)

Find the smallest point of dis[i]

vis [Location] = 1

For (points connected to the points found)

      if(dis[find]+w[find][i]<dis[i])

      {

1. Relaxation

2.pre[i]=find record precursor

      }

end

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int a[101][101];
 6 int dis[101];
 7 int maxn=0x7f;
 8 int vis[1001];
 9 int pass[1001];
10 void print(int bg,int ed)
11 {
12     int ans[101];
13     int now=1;
14     ans[now]=ed;
15     now++;
16 //    ans[now]=ed;
17     //now++;
18     int tmp=pass[ed];
19     while(tmp!=bg)
20     {
21         ans[now]=tmp;
22         now++;
23         tmp=pass[tmp];
24     }
25     ans[now]=bg;
26     for(int i=now;i>=1;i--)
27     {
28         if(i!=1)
29         printf("%d-->",ans[i]);
30         else
31         printf("%d",ans[i]);
32     }
33 }
34 int main()
35 {
36     memset(a,maxn,sizeof(a));
37     int n,m;
38     int beginn=1;
39     scanf("%d%d",&n,&m);
40     for(int i=1;i<=m;i++)
41     {
42         int x,y,zhi;
43         scanf("%d%d%d",&x,&y,&zhi);
44         a[x][y]=zhi;
45         a[y][x]=zhi;
46     }
47     
48     for(int i=1;i<=n;i++)
49     {
50         if(a[beginn][i]!=maxn)
51         {
52             dis[i]=a[beginn][i];
53         }
54     }
55     dis[beginn]=0;
56     for(int i=1;i<=n;i++)
57     {
58         int minn=maxn;
59         int k=-1;
60         for(int j=1;j<=n;j++)
61         {
62             if(dis[j]<=minn&&vis[j]==0)
63             {
64                 minn=dis[j];
65                 k=j;
66             }
67         }
68         vis[k]=1;
69         for(int j=1;j<=n;j++)
70         {
71             if(dis[k]+a[k][j]<=dis[j])
72             {
73                 dis[j]=dis[k]+a[k][j];
74                 pass[j]=k;
75             }
76         }
77     }
78     for(int i=1;i<=n;i++)
79     {
80     cout<<dis[i]<<" ";
81     if(i==1)cout<<i;
82     else
83     print(1,i);
84     cout<<endl;
85     }
86     
87     return 0;
88 }
Dijkstra

SPFA

Main idea: Initially join the starting point in the queue. Each time an element is extracted from the queue, and all the points adjacent to it are modified. If a point adjacent to it is modified successfully, it will join the queue. Until the queue ends in empty time

Thought: Variables are needed:

1. A dis array is needed to record the shortest path from the required point to the other point.

2.pre array record precursor

Queue queue

4.vis array records whether the point is in the queue

  begin

Initialization: dis []= dis [starting point] = 0 pre [starting point] = 0

2. While (the queue is not empty)

(1) Take out the vertex vis [vertex] = false

(2) For (points connected to vertices)

      if(dis[find]+w[find][i]<dis[i])

      {
1. Relaxation

if(i is not in the queue)

        {

Join the queue

          vis[i]=true;

        }           

      }

end;

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 int map[101][101];
 7 int dis[101];
 8 bool vis[101];
 9 queue<int>q;
10 int n,m;
11 int bg=1;
12 void spfa()
13 {
14     dis[bg]=0;
15     vis[bg]=1;
16     q.push(bg);
17     dis[bg]=0;
18     do
19     {
20         int k=q.front();    
21         for(int j=1;j<=n;j++)
22         {
23             if(dis[j]>dis[k]+map[k][j])
24             {
25                 dis[j]=dis[k]+map[k][j];
26                 if(vis[j]==0)
27                 {
28                     q.push(j);
29                     vis[j]=1;
30                 }
31             }
32         }
33         q.pop();
34         vis[k]=0;
35     }while(q.size()!=0);
36     for(int i=1;i<=n;i++)
37     cout<<dis[i]<<endl;
38 }
39 int main()
40 {
41     memset(map,0x7f,sizeof(map));
42     memset(dis,0x7f,sizeof(dis));
43     memset(vis,0,sizeof(vis));
44     scanf("%d%d",&n,&m);
45     for(int i=1;i<=m;i++)
46     {
47         int x,y,z;
48         scanf("%d%d%d",&x,&y,&z);
49         map[x][y]=map[y][x]=z;
50     }
51     //int a,b;
52     //scanf("%d%d",&a,&b);
53     spfa();
54     return 0;
55 }
SPFA

Single source shortest path output

Main Ideas

Major use of recursive thinking, layer by layer for iteration

1 void print(int x)
2 {
3     if(pre[a][x]==0)return;
4     print(pre[a][x]);
5     cout<<"->"<<x;
6 }
7 //a For the starting point
Single Source Shortest Circuit Output

Tarjan algorithm

Ideas:

Basic ideas:

1. Initialization

2. Stacking

3. Enumeration:

1. Not in the queue - > access, assign value.

2. In the queue - > assignment

4. Finding Roots - > Output Results

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 struct node {
 6     int v,next;
 7 } edge[1001];
 8 int DFN[1001],LOW[1001];
 9 int stack[1001],heads[1001],visit[1001],cnt,tot,index;
10 void add(int x,int y) {
11     edge[++cnt].next=heads[x];
12     edge[cnt].v = y;
13     heads[x]=cnt;
14     return ;
15 }
16 void tarjan(int x) { //Represents the number of points being dealt with. The recursive point.
17     DFN[x]=LOW[x]=++tot;// Initialization of new entry points.
18     stack[++index]=x;//Arrival
19     visit[x]=1;//Represents in the stack
20     for(int i=heads[x]; i!=-1; i=edge[i].next) {
21         if(!DFN[edge[i].v]) {
22             //If you haven't visited
23             tarjan(edge[i].v);//Stretch down and start recursion
24             LOW[x]=min(LOW[x],LOW[edge[i].v]);//Recursively, compare who is whose son/Father is the corresponding relationship of trees, which involves the minimum root of strongly connected component subtrees.
25         } else if(visit[edge[i].v ]) {
26             //If visited, and still in the stack.
27             LOW[x]=min(LOW[x],DFN[edge[i].v]);//Compare who is whose son/Father. It's the link correspondence.
28         }
29     }
30     if(LOW[x]==DFN[x]) { //Discovery is the smallest root in the whole strongly connected component subtree.
31         do {
32             printf("%d ",stack[index]);
33             visit[stack[index]]=0;
34             index--;
35         } while(x!=stack[index+1]);//Out of the stack, and output.
36         printf("\n");
37     }
38     return ;
39 }
40 int main() {
41     memset(heads,-1,sizeof(heads));
42     int n,m;
43     scanf("%d%d",&n,&m);
44     int x,y;
45     for(int i=1; i<=m; i++) {
46         scanf("%d%d",&x,&y);
47         add(x,y);
48     }
49     for(int i=1; i<=n; i++)
50         if(!DFN[i])  tarjan(1);//When this point has not been visited, start at this point. Prevent the map from not running out
51     return 0;
52 }
Tarjan

Kruskal algorithm

Main ideas:

Kruskal algorithm regards a connected block as a set. Kruskal first ranks all the edges in order from small to large (usually using fast row), and considers that each point is isolated and belongs to n independent sets. Then enumerate each edge in order. If the edge is connected to two different sets, then the edge is added to the minimum spanning tree, and the two different sets are merged into one set; if the two points connected by the edge belong to the same set, they are skipped. Until n-1 edges are selected.
 
Ideas:
Algorithmic description:
1. Initialization and collection. father[x]=x.
2.tot=0
3. sort all edges from small to large in fast rows. sort
4. Counter k=0;
5. For (i = 1; I < = M; i++) // Loop all edges that have been sorted from small to large
if this is a u,v that does not belong to the same set of edges (u,v) (because it has been sorted, it must be the smallest).
    begin
(1) Merging the set of u and V is equivalent to adding edges (u,v) to the minimum spanning tree.
     ②tot=tot+W(u,v)
      ③k++
(4) If k=n-1 indicates that the minimum spanning tree has been generated, then break;
    end;
6. At the end, tot is the sum of the total weights of the smallest spanning tree.
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int map[101][101];
 6 int nmap[101][101];
 7 int pass[101];
 8 int vis[101];
 9 int now=1;
10 int n,m;
11 int num=0;
12 void dfs(int p)
13 {
14     vis[p]=1;
15     for(int i=1;i<=n;i++)
16     {
17         if(vis[i]==0&&map[p][i]==1)
18         {
19             dfs(i);
20         
21         }
22     }
23     pass[now]=p;
24     now++;
25 }
26 void ndfs(int p)
27 {
28     vis[p]=0;
29     for(int i=1;i<=n;i++)
30     {
31         if(vis[i]==1&&nmap[p][i]==1)
32         ndfs(i);
33     }
34 }
35 int main()
36 {
37     
38     scanf("%d%d",&n,&m);
39     for(int i=1;i<=m;i++)
40     {
41         int x,y;
42         scanf("%d%d",&x,&y);
43         map[x][y]=1;
44         nmap[y][x]=1;
45     }
46     for(int i=1;i<=n;i++)
47     {
48         if(vis[i]==0)
49         dfs(i);
50     }
51     pass[now]=1;
52     for(int i=n;i>=1;i--)
53     {
54         if(vis[pass[i]]==1)
55         {
56             ndfs(pass[i]);
57             num++;
58         }
59     }
60     cout<<num;
61     return 0;
62 }
Kruskal

 

 
 

 

 

Kruskal algorithm regards a connected block as a set. Kruskal first ranks all the edges in order from small to large (usually using fast row), and considers that each point is isolated and belongs to n independent sets. Then enumerate each edge in order. If the edge is connected to two different sets, then the edge is added to the minimum spanning tree, and the two different sets are merged into one set; if the two points connected by the edge belong to the same set, they are skipped. Until n-1 edges are selected.

Keywords: C++

Added by brem13 on Tue, 09 Jul 2019 02:58:45 +0300