cogs1685 膜法森林 神奇的SPFA
Posted Loser Of Life
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cogs1685 膜法森林 神奇的SPFA相关的知识,希望对你有一定的参考价值。
继续填坑……链接:http://cogs.pro/cogs/problem/problem.php?pid=1685
题意:两种费用,求出两种费用最小的和。
正解是$LCT$……但是这里有一个令人惊掉下巴的做法……
不断枚举每一条边所需的第一种费用,对于满足这一条件下的边加入图中,同时压入队列,随后跑最短路,跑出一次更新一次最小值……
恩就这么做出来了……
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int maxn=100005,maxm=100005; 8 int fro[maxm],too[maxm],wei1[maxm],wei2[maxm],n,m,id[maxn],dis[maxn]; 9 queue<int>q; 10 int cmp(int a,int b) 11 { 12 return wei1[a]<wei1[b]; 13 } 14 struct node 15 { 16 int from,to,dis,next; 17 }edge[maxm<<1]; 18 int head[maxn],tot; 19 void addedge(int u,int v,int w) 20 { 21 edge[++tot]=(node){u,v,w,head[u]};head[u]=tot; 22 } 23 bool inqueue[maxn]; 24 void spfa() 25 { 26 while(!q.empty()) 27 { 28 int u=q.front();q.pop();inqueue[u]=0; 29 for(int i=head[u];i;i=edge[i].next) 30 { 31 int v=edge[i].to; 32 if(dis[v]>max(dis[u],edge[i].dis)) 33 { 34 dis[v]=max(dis[u],edge[i].dis); 35 if(!inqueue[v])q.push(v),inqueue[v]=1; 36 } 37 } 38 } 39 } 40 int haha() 41 { 42 //freopen("magicalforest.in","r",stdin); 43 //freopen("magicalforest.out","w",stdout); 44 scanf("%d%d",&n,&m); 45 for(int i=1;i<=m;i++) 46 { 47 id[i]=i; 48 scanf("%d%d%d%d",&fro[i],&too[i],&wei1[i],&wei2[i]); 49 } 50 sort(id+1,id+m+1,cmp); 51 memset(dis,0x3f,sizeof(dis)); 52 dis[1]=0; 53 int cur=1,ans=0x3f3f3f3f; 54 for(;cur<=m;) 55 { 56 int tmp=wei1[id[cur]]; 57 while(wei1[id[cur]]==tmp) 58 { 59 addedge(fro[id[cur]],too[id[cur]],wei2[id[cur]]); 60 addedge(too[id[cur]],fro[id[cur]],wei2[id[cur]]); 61 q.push(fro[id[cur]]),q.push(too[id[cur]]); 62 inqueue[fro[id[cur]]]=inqueue[too[id[cur]]]=1; 63 cur++; 64 } 65 spfa(); 66 if(dis[n]<0x3f3f3f3f)ans=min(ans,dis[n]+wei1[id[cur-1]]); 67 } 68 if(ans>=0x3f3f3f3f)ans=-1; 69 printf("%d\n",ans); 70 } 71 int sb=haha(); 72 int main(){;}
以上是关于cogs1685 膜法森林 神奇的SPFA的主要内容,如果未能解决你的问题,请参考以下文章