题目链接:
题目描述:最短路最裸题
解题思路:
比赛时候用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;
}