scu4444(完全图最短路)

题目连接:https://vjudge.net/problem/SCU-4444

分两种情况,

边少(m<1e5*2)的情况直接dijkstra

边可能会很多(因为是完全图),这种情况下用bfs,用set保证每个点只入队一次。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<set>
  5 #include<algorithm>
  6 #define ll long long
  7 using namespace std;
  8 
  9 const int maxn=1e5+10;
 10 const int inf=0x3f3f3f3f;
 11 int head[maxn];
 12 int cnt=0;
 13 ll dis[maxn];
 14 
 15 int n,m;
 16 ll a,b;
 17 int u,v;
 18 
 19 struct edge
 20 {
 21     int v,w,nex;
 22 }e[maxn*10];
 23 struct node
 24 {
 25     int v;
 26     ll c;
 27     bool operator <(const node&a)const
 28     {
 29         return c>a.c;
 30     }
 31 };
 32 void init()
 33 {
 34     cnt=0;
 35    for(int i=0;i<=n;i++)
 36    {
 37        head[i]=-1;
 38    }
 39 }
 40 
 41 void add(int u,int v,int w)
 42 {
 43     e[cnt].v=v;
 44     e[cnt].w=w;
 45     e[cnt].nex=head[u];
 46     head[u]=cnt++;
 47 }
 48 ll dijkstra(int n)
 49 {
 50    for(int i=0;i<=n;i++)
 51         dis[i]=inf;
 52     priority_queue<node> pq;
 53     dis[1]=0;
 54     pq.push(node{1,0});
 55     while(!pq.empty())
 56     {
 57         node temp=pq.top();
 58         pq.pop();
 59         int u=temp.v;
 60         if(dis[u]<temp.c) continue;
 61         for(int i=head[u];i!=-1;i=e[i].nex)
 62         {
 63             int v=e[i].v;
 64             int w=e[i].w;
 65             if(dis[v]>dis[u]+w)
 66             {
 67                 dis[v]=dis[u]+w;
 68                 pq.push(node{v,dis[v]});
 69             }
 70         }
 71     }
 72     return dis[n];
 73 }
 74 
 75 ll bfs(int n,ll val)
 76 {
 77     set<int> ta,tb;
 78     queue<int>q;
 79     q.push(1);
 80     dis[1]=0;
 81     dis[n]=inf;
 82     for(int i=2;i<=n;i++) ta.insert(i);
 83     while(!q.empty())
 84     {
 85         int u=q.front();
 86         q.pop();
 87         for(int i=head[u];i!=-1;i=e[i].nex)
 88         {
 89             int v=e[i].v;
 90             if(!ta.count(v)) continue;
 91             ta.erase(v);
 92             tb.insert(v);
 93         }
 94         for(set<int>::iterator it=ta.begin();it!=ta.end();it++)
 95         {
 96             q.push(*it);
 97             dis[*it]=dis[u]+val;
 98         }
 99         ta.swap(tb);
100         tb.clear();
101     }
102     return dis[n];
103 }
104 int main()
105 {
106 
107     while(scanf("%d%d%lld%lld",&n,&m,&a,&b)!=EOF)
108     {
109         init();
110         int flag=0;
111         for(int i=0;i<m;i++)
112         {
113             scanf("%d%d",&u,&v);
114             add(u,v,a);
115             add(v,u,a);
116             if(min(u,v)==1&&max(u,v)==n) flag=1;
117         }
118         if(!flag) printf("%lld\n",min(dijkstra(n),b));
119         else printf("%lld\n",min(bfs(n,b),a));
120     }
121     return 0;
122 }

 

posted @ 2017-04-18 08:43  yijiull  阅读(400)  评论(0编辑  收藏  举报