Several shortest paths

                             **Floyd Find the shortest path O(N³)**

Given a digraph with n points and m edges, there may be multiple edges and self rings, and the edge weight may be negative.

Given k queries, each query contains two integers x and y, representing the shortest distance from point x to point y,
If the path does not exist, output impossible.

There is no negative weight loop in the data assurance diagram.

Input format
The first line contains three integers n,m,k.

The next m lines contain three integers x, y and z, indicating that there is a directed edge from point x to point y, and the edge length is z.

The next k lines contain two integers x and y, representing the shortest distance from query point x to point y.

Output format
There are k lines in total, and an integer is output for each line to represent the query result. If there is no path between two points, it will output impossible.

Data range
1≤n≤200,
1≤k≤n2
1≤m≤20000,
The absolute value of side length involved in the figure shall not exceed 10000.

Input example:
3 3 2
1 2 1
2 3 2
1 3 1
2 1
1 3
Output example:
impossible
1

#include <bits/stdc++.h>

using namespace std;
#define inf 0x3f3f3f3f
int dis[250][250];
int a[250][250];
int n,m,k;
void floyd()
{
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
            }
        }
    }
}
int main()
{
    cin >> n >>m >>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j)
            {
                dis[i][j]=0;
            }
            else
            dis[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++)
    {
        int s,e,w;
        cin >>s >>e >>w;
        dis[s][e]=min(dis[s][e],w);
    }
    floyd();
    while(k--)
    {
        int s,e;
        cin >>s >>e ;
        if(dis[s][e]>inf/2)
        cout <<"impossible"<<endl;
        else
        cout <<dis[s][e]<<endl;
    }


    return 0;
}

             **Dijkstra Seeking the shortest path (simple version) O(N²) ,Heap optimized version O(M LogN)**

Given a digraph with n points and m edges, there may be multiple edges and self rings, and all edge weights are positive.

Please find the shortest distance from point 1 to point n. if you can't walk from point 1 to point n, output − 1.

Input format
The first line contains integers n and m.

The next m lines contain three integers x, y and z, indicating that there is a directed edge from point x to point y, and the edge length is z.

Output format
Output an integer representing the shortest distance from point 1 to point n.

If the path does not exist, − 1 is output.

Data range
1≤n≤500,
1≤m≤105,
The side length involved in the figure shall not exceed 10000.

Input example:
3 3
1 2 2
2 3 1
1 3 4
Output example:
3

#include <bits/stdc++.h>

using namespace std;
int n,m;
const int N = 100010;
int head[N],dis[N];
int vis[N];
struct node
{
    int to,w;
    int ne;
}a[N];
int cnt;
void add(int x,int y,int z)
{
    cnt++;
    a[cnt].to=y;
    a[cnt].w=z;
    a[cnt].ne = head[x];
    head[x]=cnt;
}
void dijkstra()
{
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int>> > q;
    q.push({0,1});
    while(!q.empty())
    {
        int x = q.top().second;
        q.pop();
        if(vis[x])
        continue;
        vis[x]=1;
        
        for(int i = head[x];i!=-1;i=a[i].ne)
        {
            int xx = a[i].to;
            if(dis[xx]>a[i].w+dis[x])
            {
                dis[xx]=a[i].w+dis[x];
                q.push({dis[xx],xx});
            }
        }
    }
    if(dis[n]==0x3f3f3f3f)
    cout <<"-1";
    else
    cout <<dis[n];
}
int main()
{
    cin >> n >>m;
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(head,-1,sizeof(head));
    dis[1]=0;
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        cin >> x >>y >>z;
        add(x,y,z);
    }
    dijkstra();
    
    return 0;
}
           **bellman-ford Application - shortest path with side limit (O (MN) )**

Given a digraph with n points and m edges, there may be multiple edges and self rings, and the edge weight may be negative.

Please find the shortest distance from point 1 to point n passing through k edges at most. If you can't go from point 1 to point n, output impossible.

Note: there may be negative weight circuit in the figure.

Input format
The first line contains three integers n,m,k.

The next m lines contain three integers x, y and z, indicating that there is a directed edge from point x to point y, and the edge length is z.

Output format
Output an integer representing the shortest distance from point 1 to point n through up to k edges.

If there is no path that meets the condition, output impossible.

Data range
1≤n,k≤500,
1≤m≤10000,
The absolute value of any side length shall not exceed 10000.

Input example:
3 3 1
1 2 1
2 3 1
1 3 3
Output example:
3

#include <bits/stdc++.h>

using namespace std;
struct node
{
    int u,v,w;
}a[10010];
int dis[10010];
int back[10010];
int n,m,k;
void bellman_ford()
{
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    for(int i=0;i<k;i++)
    {
        memcpy(back,dis,sizeof(dis));
        for(int j=0;j<m;j++)
        {
            int x=a[j].u,y=a[j].v,z=a[j].w;
            
           dis[y] = min(dis[y],back[x]+z);
        }
    }
    if(dis[n]>0x3f3f3f3f/2)
    cout <<"impossible";
    else
    cout <<dis[n];
}
int main()
{
    cin >> n >>m>> k;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        cin >>x>>y>>z;
        a[i]={x,y,z};
    }
    bellman_ford();
    
    
    
    return 0;
}
                          spfa Find the shortest path(commonly O(M)worst O(NM))

Given a digraph with n points and m edges, there may be multiple edges and self rings, and the edge weight may be negative.

Please find the shortest distance from point 1 to point n. if you can't walk from point 1 to point n, output impossible.

The data guarantees that there is no negative weight loop.

Input format
The first line contains integers n and m.

The next m lines contain three integers x, y and z, indicating that there is a directed edge from point x to point y, and the edge length is z.

Output format
Output an integer representing the shortest distance from point 1 to point n.

If the path does not exist, output impossible.

Data range
1≤n,m≤105,
The absolute value of side length involved in the figure shall not exceed 10000.

Input example:
3 3
1 2 5
2 3 -3
1 3 4
Output example:
2

#include <bits/stdc++.h>

using namespace std;
int n,m;
int cnt;
int dis[100010];
int head[100010];
bool st[100010];
struct node
{
    int ne,to,w;
}a[100010];
bool s;
void add(int x,int y,int z)
{
    cnt++;
    a[cnt].to=y;
    a[cnt].w=z;
    a[cnt].ne=head[x];
    head[x]=cnt;
}
void spfa()
{
    queue<int> q;
    q.push(1);
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        st[now]=false;
        for(int i=head[now];i!=-1;i=a[i].ne)
        {
            int xx=a[i].to,yy=a[i].w;
            if(dis[xx]>dis[now]+yy)
            {
                dis[xx]=dis[now]+yy;
                if(!st[xx])
                {
                    q.push(xx);
                    st[xx]=true;
                }
            }
            
        }
    }
    if(dis[n]>0x3f3f3f3f/2)
    cout <<"impossible";
    else 
    cout <<dis[n];
}
int main()
{
    cin >> n >>m;
    memset(head,-1,sizeof(head));
     memset(dis,0x3f,sizeof(dis));
     dis[1]=0;
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        cin >>x>> y >>z;
        add(x,y,z);
    }
    spfa();
    return 0;
}
                           spfa Judgment negative ring 

Given a digraph with n points and m edges, there may be multiple edges and self rings, and the edge weight may be negative.

Please judge whether there is a negative weight circuit in the figure.

Input format
The first line contains integers n and m.

The next m lines contain three integers x, y and z, indicating that there is a directed edge from point x to point y, and the edge length is z.

Output format
If there is a negative weight circuit in the figure, output Yes, otherwise output No.

Data range
1≤n≤2000,
1≤m≤10000,
The absolute value of side length involved in the figure shall not exceed 10000.

Input example:
3 3
1 2 -1
2 3 4
3 1 -4
Output example:
Yes

#include <bits/stdc++.h>

using namespace std;
bool st[2100],num[2100];
int dis[2100],head[21000];
struct node
{
    int ne,w,to;
}a[21000];
int cnt;
void add(int x,int y,int z)
{
    cnt++;
    a[cnt].to=y;
    a[cnt].w=z;
    a[cnt].ne=head[x];
    head[x]=cnt;
}
int n,m;
void spfa()
{
    queue<int> q;
    
    for(int i=1;i<=n;i++)
    {
        q.push(i);
        st[i]=true;
    }
    while(!q.empty())
    {
        int now = q.front();
        q.pop();
        st[now]=false;
        for(int i=head[now];i!=-1;i=a[i].ne)
        {
            int xx=a[i].to,ww=a[i].w;
            if(dis[xx]>dis[now]+ww)
            {
                dis[xx]=dis[now]+ww;
                num[xx]=num[now]+1;
                if(num[xx]>=n)
                {
                    cout <<"Yes";
                    exit(0);
                }
                if(!st[xx])
                {
                    st[xx]=true;
                    q.push(xx);
                }
            }
        }
    }
    cout <<"No";
}
int main()
{
    cin >> n >>m;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        cin >> x >> y>>z;
        add(x,y,z);
    }
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    spfa();
    return 0;
}

Tags: data structure Graph Theory

Posted on Sun, 05 Dec 2021 06:19:10 -0500 by khalidorama