Qing North NOIP training camp notes - Graph Theory (increase group elite classes)

Qing North NOIP training camp notes - Graph Theory (increase group elite classes)

This article is from the Qing North school internal graph theory notes, authored by Pan Kai Fan, willow iron from a clear North had participated in training camp to improve the elite group classes, notes in great detail, especially to share to you! For more information about learning resources focus on micro-channel subscription number noipnoi.

Shortest Path:

1.Floyd algorithms (interpolation point method):

By weight to obtain a map value matrix of each of its shortest path between two points (multi-source shortest).

Algorithm Description:

A very violent and classic DP, suppose i to j path has two states:

①i and immediately connected to path j:

And j ②i indirect link, the middle link node number k:

Suppose DIS [i] [j] represents the shortest path i to j, k for each node exists, we checked again dis [i] [k] + dis [k] [j].

 

// Floyd algorithm, the time complexity: O (n ^ 3) 

// Floyd algorithm, the time complexity: O (n ^ 3) 

int dis[MAXN][MAXN];

for (k = 1; k <= n; k ++) // Enumeration 

{

    for(i=1;i<=n;i++)

    {

        for(j=1;j<=n;j++)

        {

            December [i] [j] = min (DIS [i] [j], disincentives [i] [k] + December [k] [j]); // DP

        }

    }

}

[Qing North 2019NOIP summer camp help you to realize their dreams OI]

2.Dijkstra algorithm (undirected graph, no negative right side):

Algorithm Description:

Multi-source shortest!

a. initially, S contains only the source, i.e., S = {v}, v is from 0. U contains in addition other vertex v, namely: U = {} remaining vertices, if the vertex u and v edged U, then <u, v> entitled normal value, v if u is not adjacent to the side of the point, <u, v> with a weight of ∞.

B. v select a minimum distance from the vertex U k in the k, the addition of S (the distance v is selected to k shortest path length).

. C to k is the midpoint of new considered modified from U each vertex; if from a source point v to vertex u distance (through the vertex k) (without the vertex k) shorter than the original distance, the modified vertex u distance value, the distance from the vertex k value plus modified right edge.

d. Repeat steps b and c until all vertices contained in S.

The concept of a mess ah ~ above is too complicated to understand, or give you an example! As shown below!

 

We assume that the node number 1 is the origin.

The first round, we can calculate the distance from the origin node 2,3,4,5,6 No. 1 to as [7,9, ∞, ∞, 14 ], ∞ represents infinity (not communicating directly between nodes), taking the minimum of 7, it is determined that the shortest path 1-> 0,1- shortest path 1 is> 2 to 7 while taking the shortest path to the next node and the smallest one of the predecessor nodes.

The second round, taken predecessor node is node 2, node according to the origin of the precursor + the shortest distance from the new node to the predecessor node to calculate a new minimum distance can be obtained from a number of the origin node 3,4,5,6 as [17,22, ∞, ∞] (the new node must be back to square one node No. 2), this time the need to compare the results and the results of the new round of computing, No. 3 node: 17> 9, the shortest path is still 9; node 4: 22 <∞, update number 4 is the shortest path node 22; node 5: ∞ remains unchanged; node No. 6: 14 <∞, 6 updates the shortest path to node 14. The shortest distance is obtained round [9,22, ∞, 14], the shortest path 1-> 3 to 9, while taking the shortest path for the next minimum node 3 a predecessor node.

Third round: On the same token, the node 3 to the node as precursor can be obtained 4,5,6 node is from the origin to 1 [20, ∞, 11], according to the principles of the shortest path, the shortest distance, and an upper comparison, refresh [20, ∞, 11], the shortest path 1-> 3-> 6 to 11, while taking the shortest path for the next minimum node 6 a predecessor node.

Fourth round: Similarly, the shortest distance to give 4,5 nodes [20, 20], these two values are equal, the end of the calculation, the shortest distance from these two dots are 20, if the two values are not equal , but also for the fifth round operation!

#include<cstdio>

#include<cstring>

const int N=100500;

const int M=200500;

int point[N]={0},to[M]={0},next[M]={0},len[M]={0},cc=0;

int dis [N]; // shortest length, dis [i] denotes the i-th point source (point 1) is the shortest distance

bool ever [N]; // current node has not determined the shortest 

int n,m; 

void AddEdge (int x, int y, int z) // add new nodes and edges: x side length of z to y

{

    cc++;

    next[cc]=point[x];

    point[x]=cc;

    to[cc]=y;

    len [cc] = z; // len recording side length x to y 

}

int main ()

{

    int i,j,k;

    scanf("%d%d",&n,&m);

    for(i=1;i<=m;i++)

    {

        int a,b,c;

        scanf("%d%d%d",&a,&b,&c);

        AddEdge (a, b, c); // undirected graph, to add twice 

        AddEdge(b,a,c);

    }

    memset (dis, 0x3f, sizeof dis); // initialize a maximum value 

    dis [1] = 0; // to their node number 1 is the shortest distance 0 

    for(k=1;k<=n;k++)

    {

        int minp,minz=123456789;

        for(i=1;i<=n;i++)

        {

            if(!ever[i])

            {

                if(dis[i]<minz)

                {

                    minz=dis[i];

                    minp=i;

                }

            }

        }

        ever[minp]=1;

        int now=point[minp];

        while(now)

        {

            int tox=to[now];

            if(dis[tox]>dis[minp]+len[now])

            dis[tox]=dis[minp]+len[now];

            now=next[now];

        }

    }

    for(i=1;i<=n;i++)

        printf("%d\n",dis[i]);

return 0;

[Qing North 2019NOIP camp at your feet the way OI]

 

3.SPFA algorithm (the right side has a negative, no negative ring, but not able to detect negative output ring):

Multi-source shortest!

Dijkstra and SPFA very similar, but added a queue optimized to detect the negative ring and negative weights of the edges.

Algorithm Description:

The establishment of a queue, the queue only when the initial starting point, and then create a form to record the shortest path to the starting point of all points (initial value of the table to assign a maximum value, that point to the path of his own assigned 0). Relaxation operation is then performed, with some of the queue as the starting point to the shortest refresh all points, and is successfully refreshed if the refresh point is not put in the queue of the final points to the queue. Repeat until the queue is empty.

Determine whether the negative ring:
If the number of the queue exceeds a certain Enter ring there negative N times (FIG negatively not process the SPFA ring)

#include<cstdio>

#include<cstring>

const int N=100500;

const int M=200500;

int point[N]={0},to[M]={0},next[M]={0},len[M]={0},cc=0;

int dis [N]; // shortest length

int queue [N], top, tail; // bidirectional queue Queue, HOL, the tail 

bool in [N]; // record the point in the not in the queue, expressed in 1, 0 indicates not 

int n, m; // n nodes, m edges 

void AddEdge (int x, int y, int z) // x side length z to y 

{

    cc++;

    next[cc]=point[x];

    point[x]=cc;

    to[cc]=y;

    as [a] = z;

}

int main ()

{

    int i,j;

    scanf("%d%d",&n,&m);

    for(i=1;i<=m;i++)

    {

        int a,b,c;

        scanf("%d%d%d",&a,&b,&c);

        AddEdge (a, b, c); // Since bidirectional queue, plus a left and right plus one

        AddEdge(b,a,c);

    }

    memset (dis, 0x3f, sizeof dis); // initialize a maximum value

    dis [1] = 0; // to their node number 1 is the shortest distance 0 

    top = 0; tail = 1; queue [1] = 1; in [1] = 1; // initializes, only the addition of origin 

    while(top!=tail)

    {

        top++;

        top%=N;

        int now=queue[top];

        in[now]=0;

        int ed=point[now];

        while(ed)

        {

            int tox=to[ed];

            if(dis[tox]>dis[now]+len[ed])

            {

                dis[tox]=dis[now]+len[ed];

                if(!in[tox])

                {

                    tail++;

                    tail%=N;

                    queue[tail]=tox;

                    in[tox]=1;

                }

            }

            ed=next[ed];

        }

    }

    for(i=1;i<=n;i++)

        printf("%d\n",dis[i]);

    return 0; 

}

4.Bellman Ford algorithm (negative right side, may have a negative ring, and ring detect output negative):

Single-source shortest!

Algorithm Description:

1. Initialization: the shortest distance of all vertices except source point estimate d [all] = + ∞, d [start] = 0;

2. Iterative Solution: repeatedly each side edge set E relaxation in operation, so that the shortest distance estimate for each vertex v in the set V of vertices whose shortest distance gradually approaching; (Run | v | -1 times)

3. Verify that the negative cycles: two endpoints to determine edge set E of each side converges. If not converged apex exists, then the algorithm returns false, indicates that the problem has no solution; true otherwise algorithm, and stored in D [v] the shortest distance from the source point up to the vertex v.

Briefly, as shown below:

 

Before relaxation calculation value of the point B is 8, but the value of the point A weight plus the weight of the edge 2, to give 5, than the value of point B (8) is small, therefore, the value of the point B is reduced to 5. The significance of this process is to find a path to point B Shorter route, and the route is to go through point A, then a weight of 2 sides, reaching point B

If the following situations:

 

After the relaxation operation, becomes 7,7> 6, so as not to modify (the sublime Bellman Frod in this algorithm), retain the original shortest path on OK, code is very simple to implement.

int n, m; // n points, m edges 

struct Edge // type structure defined in FIG. 

{

    int a, b, c; // a length of b to c 

}edge[];

int say [];

memset(dis,0x3f,sizeof dis);

dis[1]=0;

for(int i=1;i<n;i++)

{

    for(int j=1;j<=m;j++)

    {

        if(dis[edge[j].b]>dis[edge[j].a]+edge[j].c)

        {

            dis[edge[j].b]=dis[edge[j].a]+edge[j].c;        

        }

    }

}

5.A * algorithm:

I did not understand this stuff, so I understand the future even more of it (reluctantly face) ~

Seven, topological sorting:

For a directed acyclic graph (Directed Acyclic Graph referred to as the DAG) G be topologically sorted, all the vertices of G is arranged in a linear sequence, such that any pair of vertices FIG u and v, if the edge (u, v) ∈ E (G), the linear sequence u appears before v. Typically, such a sequence is called a linear sequence satisfy topological order (Topological Order), acronym topology sequence.

Analogy: We want to make a dish name is braised eggplant, eggplant and then the first step was to buy the ingredients, the second step is to wash the eggplant, begin the third step is to pour oil into the pan ah what seven hundred seventy-eight eight, the fourth step ... you can not buy eggplant, first wash the eggplant and ingredients, such events must be conducted in accordance with the order of these events in turn constitutes a topological sequence.

Algorithm Description:

We need a stack or queue, both can be indifferent, just to find a container to put the elements of zero maintenance up only.

① selectively into a directed graph of from 0 (no precursor) vertices, outputs it.

② to delete the node from the network, and by deleting all directed edges starting from the node.

③ Repeat the above two steps until the remaining network nodes are no longer present there is no prodromal.

Specific operation is as follows:

If the stack is not empty, a pop-up elements in the stack, and then be able to enumerate the points in each of its penetration point 1 (one side omitted), if the degree of = 0, then pushed onto the stack. 
If there is no output of all vertices, there exists a certain circumferential FIG.

// topological sort, time complexity: O (n + m) 

#include<cstdio>

#include<cstring>

const int N=100500;

const int M=200500;

int point[N]={0},to[M]={0},next[M]={0},cc=0;

int xu [N] = {0}; // stack, initially vacant, xu [0] indicates the stack size 

int in [N] = {0}; // penetration, a may reach b, in [b] ++ 

int ans [N] = {0}; // ans [0] of the entire size of topological 

int n,m; 

void AddEdge (int x, int y) // adjacency table a to b 

{

    cc++;

    next[cc]=point[x];

    point[x]=cc;

    to[cc]=y;

}

int main ()

{

    int i,j;

    scanf("%d%d",&n,&m);

    for(i=1;i<=m;i++)

    {

        int a,b;

        scanf("%d%d",&a,&b);

        in [b] ++; // count for each node of the 

        AddEdge(a,b);

    }

    for(i=1;i<=n;i++)

    {

        if (in [i] == 0) // into the node is 0, pushed onto the stack 

        xu [++ xu [0]] = i;

    }

    while(xu[0])

    {

        int now=xu[xu[0]];//出栈 

        trend [0] -;

        years [++ years [0]] = now;

        int ed=point[now];

        while(ed)

        {

            int tox=to[ed];

            in[tox]--;

            if(!in[tox])

            xu [++ xu [0]] = tox;

            ed = next [ed]; // find the next adjacent node 

        }

    }

    if (ans [0] <n) // there exist certain circumferential drawing, no result 

    printf("no solution");

    else

    {

        for(i=1;i<=n;i++)

        printf("%d ",ans[i]);

    }

    return 0;

}

 

 

Unicom components:

Strong communication: a directed graph from a to b, and can be from b to a, then a and b are strongly connected.

Strong graph: a directed graph, any pair of points meet the strongly connected, then this is called a strongly connected graph of FIG.

Strong Unicom components: There is a great intensity to the strongly connected components connected subgraphs in FIG.

Tarjan algorithm for general use with a communication component to strengthen the country:

 

Euler path Hamiltonian path:

1. Eulerian paths: a path starting stroke through each one side is formed from a certain point.

Euler: back to the beginning of the path on the basis of Euler path (from the starting point to traverse a stroke each edge).

Euler path exists:

Undirected graph: if and only if all the vertices of the drawing degree is an even degree of or in addition two outer odd rest was even.

Digraph: if and only if all the vertices of the graph or = penetration of the apex = a + 1-degree, the vertex of the other out-degree = +1, the other vertex of penetration =

Euler exist:

Undirected graph: degree of each vertex are an even number, there Euler.

Directed graph: each of the vertex is equal to a degree, there Euler.

Euler path / Euler algorithm often used Fleury algorithm:

Here we recommend a good knowledge of peace: the mysterious OIer

2. Hamiltonian path: through each point exactly once path is a Hamiltonian path.

Hamilton cycle: There Hamiltonian path between the beginning and the end edges are connected to Hamilton cycles.

 

Guess you like

Origin www.cnblogs.com/qbxt/p/10981407.html