OJ-Problems-Source/SCU/4444_lvshubao1314.cpp

113 lines
2.7 KiB
C++
Raw Permalink Normal View History

/**
SCU - 4444 -
a5e5b1~n的最短路径1e5
1n之间连边为a那么答案一定为a和一条最短的全由b组成的路径的较小者1n之间连边为b
b和一条最短的全由a组成的路径的较小者1spfa就可以了spfa
1b的边set维护一下1
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
const int maxn=100100;
int n,m,vis[maxn];
LL a,b,dis[maxn];
set<int>st,ts;
set<int>::iterator it;
int head[maxn],ip;
void init()
{
memset(head,-1,sizeof(head));
ip=0;
}
struct note
{
int v,next;
}edge[maxn*10];
void addedge(int u,int v)
{
edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++;
}
void spfa()
{
queue<int>q;
for(int i=0;i<=n;i++)dis[i]=INF;
memset(vis,0,sizeof(vis));
dis[1]=0;
q.push(1);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(dis[v]>dis[u]+1)
{
dis[v]=dis[u]+1;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
printf("%lld\n",min(dis[n]*a,b));
}
void bfs()
{
dis[n]=INF;
st.clear(),ts.clear();
for(int i=2;i<=n;i++)st.insert(i);
queue<int>q;
q.push(1);
dis[1]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(st.count(v)==0)continue;
st.erase(v),ts.insert(v);
}
for(it=st.begin();it!=st.end();it++)
{
q.push(*it);
dis[*it]=dis[u]+1;
}
st.swap(ts);
ts.clear();
}
printf("%lld\n",min(dis[n]*b,a));
}
int main()
{
while(~scanf("%d%d%lld%lld",&n,&m,&a,&b))
{
init();
int flag=0;
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
if(u>v)swap(u,v);
addedge(u,v);
addedge(v,u);
if(u==1&&v==n)flag=1;
}
if(flag)bfs();
else spfa();
}
return 0;
}