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;
}
题目链接
/*****************************************
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;
}
相关文章推荐
- ViewPager加强版
- GCC 编译linux运用程序开方错误的解决办法
- Quartus ii 12.0 和ModelSim 10.1 SE安装及连接
- [LeetCode] Perfect Squares
- 一道关于:ArrayList、Vector、LinkedList的存储性能和特性 的面试题
- 指针和C++的基本原理
- 冒泡排序和快速排序算法练习
- 程序中用到过的方法
- Android之项目推荐使用的第三方库
- 启动ie就出现“无法显示此页” 以及 360 浏览器 域名解析错误(错误代码:105) 解决办法
- My97DatePicker设置默认时间
- Django1.8教程重点
- 火狐浏览器中文乱码问题,亲自试验成功解决问题
- IG&IC&Pra 安装检查
- 后会无期
- Codeforces Round #318 (Div. 2) A - Bear and Elections 模拟暴力枚举
- 【Android技术】Android px、dp、sp之间相互转换
- iOS 截取当前屏幕的方法
- n进制转十进制
- 数学_方向导数和梯度