写这个dij+堆优化的原因是有些地方卡SPFA,只能搞这个;
香甜的奶油:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<ctime> 7 #include<vector> 8 #include<algorithm> 9 #include<queue> 10 using namespace std; 11 #define LL long long 12 const int maxn=820; 13 const int inf=1000000000; 14 int d[maxn],vis[maxn],n,m,p,b[maxn]; 15 struct node{ 16 int y,next,v; 17 }e[5000]; 18 int linkk[maxn],len=0; 19 void insert(int x,int y,int v){ 20 e[++len].y=y; 21 e[len].next=linkk[x]; 22 linkk[x]=len; 23 e[len].v=v; 24 } 25 typedef pair<int,int> pii; 26 priority_queue<pii,vector<pii>,greater<pii> > q; 27 int dij(int s){ 28 while(!q.empty())q.pop(); 29 q.push(make_pair(0,s)); 30 memset(d,10,sizeof(vis));d[s]=0; 31 memset(vis,0,sizeof(vis)); 32 while(!q.empty()){ 33 int v=q.top().first; 34 int x=q.top().second; 35 q.pop(); 36 vis[x]=1; 37 for(int i=linkk[x];i;i=e[i].next){ 38 if(vis[e[i].y])continue; 39 if(d[e[i].y]>v+e[i].v){ 40 d[e[i].y]=v+e[i].v; 41 q.push(make_pair(d[e[i].y],e[i].y)); 42 } 43 } 44 } 45 int ans=0; 46 for(int i=1;i<=n;i++)ans+=d[b[i]]; 47 return ans; 48 } 49 void init(){ 50 scanf("%d%d%d",&n,&p,&m);//cow,muchang,daolu 51 for(int i=1;i<=n;i++)scanf("%d",&b[i]); 52 int x,y,v; 53 for(int i=1;i<=m;i++){ 54 scanf("%d%d%d",&x,&y,&v); 55 insert(x,y,v);insert(y,x,v); 56 } 57 } 58 void work(){ 59 int minn=inf; 60 for(int i=1;i<=p;i++)minn=min(minn,dij(i)); 61 cout<<minn<<endl; 62 } 63 int main(){ 64 //freopen("1.in","r",stdin); 65 //freopen("1.out","w",stdout); 66 init(); 67 work(); 68 }
最后的结果是这种情况下的dij跑得比spfa慢不少;
当然可能是我用了stl,常数太大;
spfa和堆优化dij的唯一区别是一个用队列,需要多次迭代找出最优(也可能直接就找到最优值),一个用堆,可以直接找到一个不确定的点的最优值,但由于用了堆,复杂度要乘一个log;
其他的基本一样的;
spfa稀疏图好用,dij稠密图好用,上面的那道题就是个例子;