您的位置:首页 > 其它

uva10246最短路 + 枚举 + 数组记忆

2015-09-09 22:47 405 查看
思路:spfa求出每个点到其余顶点的最短路(最短路上的每个点的val都小于等于起点的val),然后又二维数组dp来保存,最后询问的时候就是枚举中间点i了,min{dp[i][u]+dp[i][v]+cost[i]};

题目链接

/*****************************************

Author :Crazy_AC(JamesQi)

Time :

File Name :

*****************************************/

#include <iostream>

#include <algorithm>

#include <string>

#include <stack>

#include <queue>

#include <vector>

#include <map>

#include <set>

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <stdlib.h>

#include <limits.h>

using namespace std;

#define FILL(a,b) memset(a,b,sizeof a)

#define CLR(a) memset(a,0,sizeof a)

template<class T> inline T Get_Max(const T&a,const T&b) {return a < b?b:a;}

template<class T> inline T Get_Min(const T&a,const T&b) {return a < b?a:b;}

const int maxn = 110;

const int inf = 1 << 30;

int dis[maxn],mark[maxn],cost[maxn],dp[maxn][maxn];

int n,m,q;

struct Edge{

int to,w;

Edge(){}

Edge(int to,int w):to(to),w(w){}

};

vector<vector<Edge> > G;

void spfa(int st)

{

// FILL(dis,inf);

fill(dis,dis + n + 2,inf);

// memset(dis,inf,sizeof dis);

// printf("%d\n",dis[1]);

FILL(mark,0);

queue<int> que;

dis[st] = 0;

mark[st] = 1;

que.push(st);

while(!que.empty())

{

int u = que.front();

que.pop();

mark[u] = 0;

for (int i = 0;i < G[u].size();i++)

{

int v = G[u][i].to;

int w = G[u][i].w;

if (dis[v] > dis[u] + w && cost[v] <= cost[st])

{

dis[v] = dis[u] + w;

if (!mark[v])

{

mark[v] = 1;

que.push(v);

}

}

}

}

for (int i = 1;i <= n;i++)

{

// printf("%d ",dis[i]);

dp[st][i] = dis[i];

}

// printf("\n");

}

int main()

{

// freopen("in.txt","r",stdin);

// freopen("out.txt","w",stdout);

int iCase = 0;

while(scanf("%d%d%d",&n,&m,&q) != EOF)

{

if (n == 0 && m == 0 && q == 0) break;

for (int i = 1;i <= n;i++)

scanf("%d",&cost[i]);

G.clear();

G.resize(n + 2);

int a,b,c;

while(m--)

{

scanf("%d%d%d",&a,&b,&c);

G[a].push_back(Edge(b,c));

G[b].push_back(Edge(a,c));

}

// FILL(dp,inf);

for (int i = 1;i <= n;i++)

for (int j = 1;j <= n;j++)

dp[i][j] = inf;

for (int i = 1;i <= n;i++)

spfa(i);

if (iCase) puts("");

printf("Case #%d\n",++iCase);

while(q--)

{

int u,v;

int ans = inf;

scanf("%d%d",&u,&v);

for (int i = 1;i <= n;i++)

{

if (dp[i][u] == inf || dp[i][v] == inf) continue;

ans = Get_Min(ans,dp[i][u] + dp[i][v] + cost[i]);

}

if (ans == inf) printf("-1\n");

else printf("%d\n",ans);

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: