51-node-1649齐头并进(最短路)

时间:2022-06-08 21:43:02

题意:中文题,没啥坑点;

解题思路:这道题一开始以为要跑两个最短路,后来发现不用,因为如果给定了铁路的线路,那么,公路一定是n个节点无向图的补图,所以,铁路和公路之间一定有一个是可以直接从1到n的,我们只需要对剩下的那个跑最短路就行了,还有一个,就是,如果这个铁路线路没有补图,那么公路就没路走,输出-1;我使用迪杰斯特拉写的,我感觉bfs代码更简洁来着;

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 200050
#define inf 0x3f3f3f3f
using namespace std;
struct Edge
{
int next;
int to;
int w;
}edge[maxn];
int head[maxn];
int dist[maxn];
int cnt;
int Map[505][505];
struct node
{
int num;
int dist;
node(int _num=0,int _dist=0):num(_num),dist(_dist){}
friend bool operator<(node a,node b)
{
return a.dist>b.dist;
}
};
void add(int u,int v,int w)
{
edge[cnt].next=head[u];
edge[cnt].to=v;
edge[cnt].w=w;
head[u]=cnt++;
}
void dij(int x)
{
memset(dist,inf,sizeof(dist));
priority_queue<node>que;
dist[x]=0;
que.push(node(x,0));
while(!que.empty())
{
node u=que.top();
que.pop();
int now=u.num;
for(int i=head[now];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dist[v]>dist[now]+edge[i].w)
{
dist[v]=dist[now]+edge[i].w;
que.push(node(v,dist[v]));
}
}
}
}
int main()
{
int n,m;
int flag=0;
int x[maxn],y[maxn];
cin>>n>>m;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
cin>>x[i]>>y[i];
Map[x[i]][y[i]]=Map[y[i]][x[i]]=1;
if(x[i]==1&&y[i]==n||x[i]==n&&y[i]==1)
flag=1;
}
if(flag==0)
{
for(int i=1;i<=m;i++)
add(x[i],y[i],1),add(y[i],x[i],1);
}
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
continue;
if(Map[i][j]==0)
{
add(i,j,1);
add(j,i,1);
}
}
}
}
dij(1);
if(dist[n]==inf)
cout<<"-1\n";
else
cout<<dist[n]<<endl;
return 0;
}