首页 > 代码库 > 没地方存代码系列————一堆最短路

没地方存代码系列————一堆最短路

http://59.77.139.92/Problem.jsp?pid=1499

FJUTOJ 1499 直接建图求s到T的最短路就可以了。

Floyd

#include <bits/stdc++.h>

using namespace std;
const int maxn = 205;

int n,m,mp[maxn][maxn];
/**

dp[k][i][j]  1~k i->j的最短路
dp[k][i][j]=min(dp[k-1][i][j],dp[k-1][i][k]+dp[k-1][k][j])

    i->k->j
    i->j 与 i->k,k->j 的最短路
    只与k,k-1省略一维度空间后
    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
*/
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                if(i==j)mp[i][j]=0;
                else mp[i][j]=1e9;
        for(int i=0; i<m; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            mp[x][y]=min(z,mp[x][y]);
            mp[y][x]=min(z,mp[y][x]);
        }
        int s,t;
        scanf("%d%d",&s,&t);
        for(int k=0; k<n; k++)
            for(int i=0; i<n; i++)
                for(int j=0; j<n; j++)
                    mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);

        if(mp[s][t]==1e9)puts("-1");
        else printf("%d\n",mp[s][t]);

    }
    return 0;
}

 SPFA+邻接表

#include <bits/stdc++.h>

using namespace std;
const int maxn = 205;
vector<pair<int,int> >E[maxn];

int n,m;
int d[maxn],inq[maxn];
void init()
{
    for(int i=0; i<maxn; i++)E[i].clear();
    for(int i=0; i<maxn; i++)inq[i]=0;
    for(int i=0; i<maxn; i++)d[i]=1e9;
}

int main()
{
    while(cin>>n>>m)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            E[x].push_back(make_pair(y,z));
            E[y].push_back(make_pair(x,z));
        }
        int s,t;
        scanf("%d%d",&s,&t);

        queue<int>Q;
        Q.push(s),d[s]=0,inq[s]=1;
        while(!Q.empty())
        {
            int now=Q.front();
            Q.pop();
            inq[now]=0;
            for(int i=0; i<E[now].size(); i++)
            {
                int v=E[now][i].first;
                if(d[v]>d[now]+E[now][i].second)
                {
                    d[v]=d[now]+E[now][i].second;
                    if(inq[v]==1)continue;
                    inq[v]=1;
                    Q.push(v);
                }
            }
        }
        if(d[t]==1e9)printf("-1\n");
        else printf("%d\n",d[t]);
    }
    return 0;
}

  

  

FJUT OJ 1443 http://59.77.139.92/Problem.jsp?pid=1443

直接建图,求1-n的最短路,dijkstra一堆for的版本

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define  INF 1<<29

using namespace std;
int mp[1005][1005],i,j,t,n,a,b,c;

void dijkstra()
{
    int minn,v,dis[1005],vis[1005]={0};
    for(i=1;i<=n;i++)
        dis[i]=mp[1][i];

    for(i=1;i<=n;i++)
    {
        minn=INF;
        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                v=j;
                minn=dis[j];
            }
        }
        vis[v]=1;

        for(j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]>mp[v][j]+dis[v])
            {
                dis[j]=mp[v][j]+dis[v];
            }
        }
    }
    printf("%d\n",dis[n]);
}

int main()
{
    while(~scanf("%d%d",&t,&n))
    {
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                {
                    mp[i][j]=0;
                }
                else
                {
                    mp[i][j]=mp[j][i]=INF;
                }
            }
        }
        for(i=0;i<t;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(mp[a][b]>c)mp[a][b]=mp[b][a]=c;
        }
        dijkstra();
    }



    return 0;
}

  

  

FJUTOJ 1456 http://59.77.139.92/Problem.jsp?pid=1456

转向次数可以看作路径长度,建图求最短路,这里用的是链式前向星+dijkstra

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define  INF 0x3fffffff

using namespace std;
const int maxn =10010;

int first[maxn],sign;

struct node
{
    int to,w,next;
}edge[maxn*2];

void creat()
{
    for(int i=0;i<maxn;i++)
        first[i]=0;
    sign=1;
}

void add_edge(int u,int v,int w)///u->v cost w
{
    edge[sign].w=w;
    edge[sign].to=v;
    edge[sign].next=first[u];
    first[u]=sign++;
}

int dij(int n,int a,int b)
{
    int dis[n+5],vis[n+5];
    int nn=n-1;
    for(int i=0;i<=n;i++)
    {
        dis[i]=INF,vis[i]=0;
    }
    dis[a]=0;
    int p=a;
    while(nn--)
    {
        vis[p]=1;
        for(int k=first[p];k;k=edge[k].next)
        {
            int to=edge[k].to;
            if(!vis[to]&&dis[to]>dis[p]+edge[k].w)
            {
                dis[to]=dis[p]+edge[k].w;
            }
        }
        int mincost=INF;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]<mincost)
            {
                mincost=dis[i];
                p=i;
            }
        }
        if(mincost==INF)return -1;
    }
    return dis[b];
}

int main()
{
    int n,a,b,num,tmp;
    while(~scanf("%d%d%d",&n,&a,&b))
    {
        creat();
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&num,&tmp);
            add_edge(i,tmp,0);
            for(int j=1;j<num;j++)
            {
                scanf("%d",&tmp);
                add_edge(i,tmp,1);
            }
        }
        int ans=dij(n,a,b);
        printf("%d\n",ans);
    }
    return 0;
}

  

  

FJUTOJ 1501 http://59.77.139.92/Problem.jsp?pid=1501

邻接矩阵+spfa

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#define  INF 1<<29
#define  MAXN 1005

using namespace std;
int n,m,s,mp[MAXN][MAXN];

int spfa(int s,int t)
{
    int dis[MAXN],inq[MAXN];
    for(int i=0;i<=n;i++)
    {
        dis[i]=INF,inq[i]=0;
    }
    queue<int>q;
    q.push(0);
    dis[0]=0,inq[0]=1;
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        inq[now]=0;
        for(int i=0;i<=n;i++)
        {
            if(dis[i]>dis[now]+mp[now][i])
            {
                dis[i]=dis[now]+mp[now][i];
                if(!inq[i])
                {
                    inq[i]=1;
                    q.push(i);
                }
            }
        }
    }
    if(dis[t]==INF) return -1;
    return dis[t];
}

int main()
{
    int u,v,w,num,tmp;
    while(~scanf("%d%d%d",&n,&m,&s))
    {
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                if(i==j)mp[i][j]=0;
                else mp[i][j]=INF;
            }
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            mp[u][v]=min(mp[u][v],w);
        }
        scanf("%d",&num);
        while(num--)
        {
            scanf("%d",&tmp);
            mp[0][tmp]=0;
        }
        printf("%d\n",spfa(0,s));
    }
    return 0;
}

  

没地方存代码系列————一堆最短路