【SPFA】-DLUT1218-裸题

来源:互联网 发布:app推广链接php源码 编辑:程序博客网 时间:2024/06/14 06:22

题目链接:

题目描述:最短路最裸题

解题思路:

比赛时候用DIJ+heap过了,注意long long 是个坑。

例会讲了SPFA算法,拿这题试验一下。

所谓SPFA就是对边进行BFS。。不太严密,应该说是通过类似于BFS的方式对dis[i]这个表示i点距起点最短距离的数组进行更新。

嗯。。用inqueue数组来判断某点是否已经在队列里,把取出的队列首点能达到的边进行以下判断:

if(dis[from]+cost<dis[to])

如果成立,更新(松弛)dis[to]的值。

并判断to是否正在队列内,不在的话就放进队列里。

AC代码:

#include <iostream>#include <cstdio>#include <queue>#include <stack>#include <algorithm>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;const int maxn=10050;struct edge{int end,cost;edge(int e,int c){end=e;cost=c;}};vector<edge> eg[maxn];int n,m;ll dis[maxn];bool inqueue[maxn];queue<int> q;ll SPFA(int S,int E){memset(dis,INF,sizeof(dis));memset(inqueue,0,sizeof(inqueue));while(!q.empty())q.pop();q.push(S);dis[S]=0;inqueue[S]=1;while(!q.empty()){int from;from=q.front();q.pop();inqueue[from]=0;for(int i=0;i<eg[from].size();i++){int to=eg[from][i].end;if(dis[from]+eg[from][i].cost<dis[to]){dis[to]=dis[from]+eg[from][i].cost;if(!inqueue[to]){q.push(to);inqueue[to]=1;}}}}return dis[E];}void add_edge(int from,int to,int w){int i,flag=0;for(i=0;i<eg[from].size();i++){if(eg[from][i].end==to){eg[from][i].cost=min(eg[from][i].cost,w);flag=1;break;}}if(!flag)eg[from].push_back(edge(to,w));}int main(){freopen("input.txt","r",stdin);int T,i,j,from,to,w,A,B,C;cin>>T;while(T--){for(i=0;i<maxn;i++)eg[i].clear();cin>>n>>m;while(m--){cin>>from>>to>>w;add_edge(from,to,w);}cin>>A>>B>>C;ll ans=0;ans+=SPFA(A,B);ans+=SPFA(B,C);cout<<ans<<endl;}    return 0;}

对SPFA的理解:

= =

本来想写。但脑子突然乱了。。怎么回事来的。。我还是先睡吧,明天的



DIJ+HEAP 方法

#include <iostream>  #include <cstdio>  #include <queue>  #include <vector>  #include <cstring>  using namespace std;     const int maxn=10050;const int INF = 0x3f3f3f3f;  typedef long long ll;typedef pair <ll,int> pii;     struct edge  {      int end;      int value;      edge(int a,int b){end=a;value=b;}  };     int vis[maxn];  ll dis[maxn];int n,m,A,B,C;  vector<edge> eg[maxn];  priority_queue <pii,vector<pii>,greater<pii> > q; void dijkstra(int st)  {      memset(dis,INF,sizeof(dis));      memset(vis,0,sizeof(vis));      while(!q.empty())q.pop();                     int from=st,to,i;      dis[from]=0;      q.push(make_pair(dis[from],from));         while(!q.empty())      {          pii t=q.top();q.pop();          from=t.second;          if(vis[from])continue;          vis[from]=1;          for(i=0;i<eg[from].size();i++)          {              to=eg[from][i].end;              if(!vis[to]&&dis[from]+eg[from][i].value<dis[to])              {                  dis[to]=dis[from]+eg[from][i].value;                      q.push(make_pair(dis[to],to));              }          }      }  } void input()  {      int flag=0,i,j,from,to,w;      while(m--)      {          cin>>from>>to>>w;          for(i=0;i<eg[from].size();i++)          {              flag=0;              if(eg[from][i].end==to)              {                  eg[from][i].value=min(eg[from][i].value,w);                flag=1;break;              }          }          if(!flag)          {              eg[from].push_back(edge(to,w));          }    }      cin>>A>>B>>C;    /*for(i=1;i<=n;i++)     {         for(j=0;j<eg[i].size();j++)             cout<<i<<"-->"<<eg[i][j].end<<"need"<<eg[i][j].value<<endl;     }     cout<<endl;     */}     int main()  {      //freopen("input.txt","r",stdin);      int i,j,T;    cin>>T;      while(T--)      {          ll ans=0;        cin>>n>>m;        for(i=0;i<maxn;i++)eg[i].clear();          input();          dijkstra(A);          ans+=dis[B];        dijkstra(B);          ans+=dis[C];        cout<<ans<<endl;    }      return 0;  }  


0 0
原创粉丝点击