分析:这题目我想了半天,其实是想到枚举汇合点的。。但是我以为两头牛相遇以后一定得一起走。。那岂不是要跑分层图?woc分层图还WA?看了题解才发现原来直接枚举汇合点就行了,凎。这是出题人的锅吧喂!然而别人跟我解释说。。人家那里用的是can不是must,是我语文不好我还是滚回去学文化课吧。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
int w1,w2,w3,n,m;
const int N=3e5+5;
int head[N],next[N],go[N],vis[N],q[N];
int dis1[N],dis2[N],disn[N];
inline void spfa1(int s)
{
memset(dis1,127/3,sizeof(dis1));
vis[s]=1;
q[1]=s;
dis1[s]=0;
int t=0,w=1;
while (t<w)
{
int x=q[++t];
int i=head[x];
while (i)
{
int v=go[i];
if (dis1[x]+1<dis1[v])
{
dis1[v]=dis1[x]+1;
if (!vis[v])
{
vis[v]=1;
q[++w]=v;
}
}
i=next[i];
}
vis[x]=0;
}
}
inline void spfa2(int s)
{
memset(dis2,127/3,sizeof(dis2));
vis[s]=1;
dis2[s]=0;
q[1]=s;
int t=0,w=1;
while (t<w)
{
int x=q[++t];
int i=head[x];
while (i)
{
int v=go[i];
if (dis2[x]+1<dis2[v])
{
dis2[v]=dis2[x]+1;
if (!vis[v])
{
vis[v]=1;
q[++w]=v;
}
}
i=next[i];
}
vis[x]=0;
}
}
inline void spfan(int s)
{
memset(disn,127/3,sizeof(disn));
vis[s]=1;
disn[s]=0;
q[1]=s;
int t=0,w=1;
while (t<w)
{
int x=q[++t];
int i=head[x];
while (i)
{
int v=go[i];
if (disn[x]+1<disn[v])
{
disn[v]=disn[x]+1;
if (!vis[v])
{
vis[v]=1;
q[++w]=v;
}
}
i=next[i];
}
vis[x]=0;
}
}
int tot=0;
inline void add(int x,int y)
{
go[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
int main()
{
scanf("%d%d%d%d%d",&w1,&w2,&w3,&n,&m);
fo(i,1,m)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
spfa1(1),spfa2(2),spfan(n);
int ans=1000000000;
fo(i,1,n)
{
int ans1=dis1[i]*w1+dis2[i]*w2+disn[i]*w3;
ans=min(ans,ans1);
}
printf("%d\n",ans);
return 0;
}