【笔记】最短路

floyd

for (k = 1; k <= n; k++) 
    for (x = 1; x <= n; x++) 
        for (y = 1; y <= n; y++) 
            f[x][y] = min(f[x][y], f[x][k] + f[k][y]);                

时间复杂度是O(n3) ,空间复杂度是O(n2) 

三种用法:

  1>多源最短路

  2>传递闭包:已知一个有向图中任意两点之间是否有连边,要求判断任意两点是否连通。

  3>求最小环

例题:sightseeing

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n,m;
const int N=103,inf=0x3f3f3f3f;
int a[N][N],d[N][N],path[N][N];//真实路径长,最短距离,切割点 
int ans=inf;

vector <int> pth;
void get_path(int x,int y)
{
    if(!path[x][y]) return ;
    get_path(x,path[x][y]);
    pth.push_back(path[x][y]); 
    get_path(path[x][y],y);
}

signed main()
{
    memset(a,0x3f,sizeof(a));
    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) a[i][i]=0;
    int u,v,w;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        a[u][v]=a[v][u]=min(w,a[v][u]);
    } 
    
    memcpy(d,a,sizeof(a));
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<k;i++)
            for(int j=i+1;j<k;j++)
                if( (long long)d[i][j]+a[i][k]+a[j][k]<ans)
                {
                    ans=d[i][j]+a[i][k]+a[j][k];
                    
                    pth.clear() ;
                    pth.push_back(i);
                    get_path(i,j); 
                    pth.push_back(j),pth.push_back(k);  
                }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(d[i][k]+d[k][j] <d[i][j])
                {
                    d[j][i]=d[i][j]=d[i][k]+d[k][j];
                    path[j][i]=path[i][j]=k;//一改,就要改一双,节省时间 
                }
    }
    
    if(ans==inf)
        puts("No solution.");
    else 
    {
        int sz=pth.size() ;
        for(int i=0;i<sz;i++)
            printf("%d ",pth[i]);
        printf("\n");
    }
    
    return 0;
}

2>求严格次短路

#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
const int N=5003,M=1e5+3;
struct node
{
    int v,w;
    bool operator < (const node & o) const
    { return w>o.w; }
    node(int vv,int ww)
    {v=vv,w=ww;}
    node(){}
};
vector <node > g[N];
int d1[N],d2[N];
priority_queue <node > q;

void dijk()
{
    memset(d1,0x3f,sizeof(d1));
    memset(d2,0x3f,sizeof(d2));
    d1[1]=0; 
    q.push(node(1,0 ));
    
    while(!q.empty())
    {
        node nw=q.top() ;q.pop() ;
        if(nw.w >d2[nw.v ]) continue;
        
        int sz=g[nw.v ].size() ;
        for(int i=0;i<sz;i++)
        {
            int nx=g[nw.v ][i].v ,w=g[nw.v ][i].w ;
            if(d1[nx]> nw.w +w)
            {
                d2[nx]=d1[nx],d1[nx]=nw.w +w;
                q.push(node(nx,d1[nx])) ;
            }
            else if(d1[nx]!=nw.w +w && d2[nx]> nw.w +w) 
            {
                d2[nx]=nw.w +w;
                q.push(node(nx,d2[nx])); 
            }
        }
    }
    
    printf("%d\n",d2[n]);
}

int main()
{
    scanf("%d%d",&n,&m);
    int u,v,w;
    while(m--)
    {
        scanf("%d%d%d",&u,&v,&w);
        g[u].push_back(node(v,w)) ;
        g[v].push_back(node(u,w)) ;
    }
    
    dijk();
    
    return 0;
}

 

posted @ 2019-09-10 22:01  心若笺诗  阅读(145)  评论(0编辑  收藏  举报