http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=184147
题意:
给定一个完全图,其中有两种边,长度为a(不超过5e5)或长度为b(剩下的),求有1~n的最短路径(数据范围1e5) #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<cstring> #include<set> using namespace std; #define inf 0x3f3f3f3f struct node { int v,val; node(int w,int x):v(w),val(x) {} bool friend operator<(const node a,const node b) { return a.val>b.val; } }; struct Egda { int v,val,next; }eadg[1000010]; int head[1000010],p; int n,m,a,b; inline void add(int u,int v,int val) { eadg[p].v=v; eadg[p].val=val; eadg[p].next=head[u]; head[u]=p++; } int dis[1000010]; int vis[1000010]; void dijk() { priority_queue<node>q; memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; q.push(node(1,dis[1])); while(!q.empty()) { node ss=q.top(); q.pop(); if(vis[ss.v]) continue; vis[ss.v]=1; for(int i=head[ss.v];~i;i=eadg[i].next) { if(!vis[eadg[i].v]&&dis[eadg[i].v]>dis[ss.v]+eadg[i].val) { dis[eadg[i].v]=dis[ss.v]+eadg[i].val; q.push(node(eadg[i].v,dis[eadg[i].v])); } } } cout<<(dis[n]<b?dis[n]:b)<<endl; } void bfs() { dis[1]=0; dis[n]=inf; set<int>q,e; set<int>::iterator it; q.clear(); e.clear(); for(int i=2;i<=n;i++) q.insert(i); queue<int>qq; qq.push(1); while(!q.empty()) { int o=qq.front(); qq.pop(); for(int i=head[o];~i;i=eadg[i].next) { if(q.count(eadg[i].v)) { q.erase(eadg[i].v); e.insert(eadg[i].v); } } for(it=q.begin();it!=q.end();it++) { dis[*it]=dis[o]+1; qq.push(*it); } q=e; e.clear(); } cout<<(a<dis[n]*b?a:dis[n]*b)<<endl; } int main() { while(cin>>n>>m>>a>>b) { p=0; memset(head,-1,sizeof(head)); int flag=0; for(int i=0;i<m;i++) { int u,v,val=a; cin>>u>>v; if(u>v) swap(u,v); add(u,v,val); add(v,u,val); if(u==1&&v==n) flag=1; } if(a==b) cout<<a<<endl; else if(!flag) { dijk(); } else { bfs(); } } return 0; } 这道题很6,set用的很巧妙。 这道题分两种情况最后附上我参考的大佬博客: 神奇的传送门