算法题——铁路与公路

题目

代码

floyd

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N = 410;
const int INF = 0x3f3f3f3f;
int n,m;
int f[N][N],g[N][N];
int floyd(int d[][N])
{
    //特判
    if(d[1][n] == 1)
    {
        return d[1][n];
    }
    for(int k=1; k<=n; k++)
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                d[i][j]=min(d[i][j], d[i][k]+d[k][j]);
            }
        }
    }
    return d[1][n];
}
int main()
{
    cin>>n>>m;
    memset(f, 0x3f, sizeof f);
    memset(g, 0x3f, sizeof g);
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        f[a][b] = f[b][a] =1;
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i!=j && f[i][j]!=1)
            {
                g[i][j]=1;
            }
        }
    }
    int ans = max(floyd(f), floyd(g));
    if(ans==INF) ans=-1;
    cout<<ans<<endl;
    return 0;
}

spfa

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int N = 410;
const int M = 160010;
const int INF = 0x3f3f3f3f;
int n,m;
bool f[N][N];
int h1[N],h2[N],e[M],ne[M],idx;
int q[N],dist[N];
bool st[N];
void add(int h[], int a, int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int spfa(int h[], bool flag)
{
    if((flag==false && f[1][n])||(flag==true && !f[1][n])) return 1;
    memset(dist, 0x3f, sizeof dist);
    int hh=0, tt=0;//tt从0开始是因为下面循环条件是hh!=tt,如果tt还是从-1开始,不会开始循环
    q[tt++]=1;
    dist[1]=0;
    while(hh!=tt)
    {
        int t=q[hh++];
        if(hh==N) hh=0;
        st[t]=false;
        for(int i=h[t]; i!=-1; i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+1)
            {
                dist[j]=dist[t]+1;
                if(!st[j])
                {
                    q[tt++]=j;
                    if(tt==N) tt=0;
                    st[j]=true;
                }
            }
        }
    }
    return dist[n];
}
int main()
{
    cin>>n>>m;
    memset(h1, -1, sizeof(h1));
    memset(h2, -1, sizeof(h2));
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        add(h1,a,b);
        add(h1,b,a);
        f[a][b]=f[b][a]=true;
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<i; j++)
        {
            if(f[i][j]==false)
            {
                add(h2, i, j);
                add(h2, j, i);
            }
        }
    }
    int ans = max(spfa(h1, false), spfa(h2, true));
    if(ans==INF) ans=-1;
    cout<<ans<<endl;
    return 0;
}
/*
直接把铁路和公路分开求就可以了,不用考虑铁路和公路会有同时在某个城市的可能性
假设从1到k城市之间有铁路,那么从1到k城市之间一定没有公路,题目规定两个城市之间铁路和公路只有一种
所以从1到k城市如果走公路就会有一条先从1到其他城市,再从其他城市到k的公路
这条公路的长度一定比走铁路的长,因此走铁路和公路不可能同时到达
*/
posted @ 2023-03-27 15:00  HD0117  阅读(13)  评论(0编辑  收藏  举报