51nod1649-二维最短路|(补图&最短路)-齐头并进

来源:互联网 发布:java遍历jsonobject 编辑:程序博客网 时间:2024/06/08 15:51

https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1649
我觉得我这个方法已经是非常好了qwq。
后来百度了,别人的更好qwq
要不火车一步到达,要不汽车一步到达。
我们只需要判定一下谁先到达,然后对剩下的那几个求一下最短路,然后输出就可以了qwq
我的思路是,求一下二维最短路,一维是火车的,另一维是汽车的。(这还是看景驰那道题想的qwq)

#include <bits/stdc++.h>using namespace std;/* 其实我差不多已经确定了,这道题是 二维最短路。存两维,一维是火车的,一维是汽车的。然后再进行的时候 spfa两次,不让他们的时间相同。最后我再求 两个时间max就可以辣!*/const int maxn=500;int dp[2][maxn];int m,n;vector<int>g1[maxn];vector<int>g2[maxn];bool mp[maxn][maxn];bool vis[maxn];const int inf=0x3f3f3f3f;void add1(int a,int b){    g1[a].push_back(b);    g1[b].push_back(a);}void add2(int a,int b){    g2[a].push_back(b);    g2[b].push_back(a);}void spfa1(){    queue<int>q;    memset(vis,false,sizeof(vis));    for(int i=0;i<maxn;i++){        dp[0][i]=0x3f3f3f3f;    }    q.push(1);    vis[1]=true;    dp[0][1]=0;    while(!q.empty()){          int u=q.front();          q.pop();          vis[u]=false;          for(int i=0;i<g1[u].size();i++){             int to=g1[u][i];             if(dp[0][to]>dp[0][u]+1){                dp[0][to]=dp[0][u]+1;                if(!vis[to]){                    vis[to]=true;                    q.push(to);                }             }          }    }}void spfa2(){    queue<int>q;    memset(vis,false,sizeof(vis));    for(int i=0;i<maxn;i++){        dp[1][i]=0x3f3f3f3f;    }    q.push(1);    vis[1]=true;    dp[1][1]=0;    while(!q.empty()){          int u=q.front();          q.pop();          vis[u]=false;          for(int i=0;i<g2[u].size();i++){             int to=g2[u][i];             if(dp[1][to]>dp[1][u]+1){                if((dp[1][u]+1)!=dp[1][to]){                dp[1][to]=dp[1][u]+1;                   if(!vis[to]){                    vis[to]=true;                    q.push(to);                   }                }             }          }    }}int main(){   int a,b;    scanf("%d%d",&m,&n);    for(int i=0;i<n;i++){        scanf("%d%d",&a,&b);        mp[a][b]=true;        mp[b][a]=true;        add1(a,b);    }    for(int i=1;i<=m;i++){        for(int j=1;j<=m;j++)        if(!mp[i][j]){            mp[i][j]=true;            mp[j][i]=true;            add2(i,j);        }    }    spfa1();    spfa2();    if(dp[0][m]==inf||dp[1][m]==inf){        puts("-1");    }    else{        printf("%d\n",max(dp[0][m],dp[1][m]));    }    return 0;}

直接一次也行。一样的