http://acm.hdu.edu.cn/showproblem.php?pid=2066
用dijistra:
不同一般的题目,这个题目是多个起点 多个终点的;
对不同起点 求最短路,求出不同终点的最小值;
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 1003
#define INF 0x3f3f3f3f
using namespace std;
int T,S,D;
int map[maxn][maxn]; //地图
bool visit[maxn]; //访问标记
int dis[maxn]; //到起点 距离
int Scity[maxn]; //起点集
int Dcity[maxn]; //终点集
int dijkstra(int source)
{
memset(visit,false,sizeof(visit));
for(int i = 1; i <= maxn; i++)
dis[i] = map[source][i];
dis[source] = 0;
for(int i = 1; i <= maxn; i++)
{
int p = INF,u = -1;
for(int j = 1; j <= maxn; j++)
{
if(!visit[j] && dis[j] < p)
{
p = dis[j];
u = j;
}
}
if(u != -1)
{
visit[u] = true;
for(int j = 1; j <= maxn; j++)
{
if(!visit[j] && dis[j] > dis[u] + map[u][j]) //Relax()
dis[j] = dis[u] + map[u][j];
}
}
}
int mintime = INF;
for(int i = 1; i <= D; i++)
{
mintime = min(mintime, dis[Dcity[i]]);
}
return mintime;
}
int main()
{
int a,b,c;
while(scanf("%d%d%d",&T,&S,&D)!=EOF)
{
memset(map,0x3f,sizeof(map));
for(int i = 1; i <= T; i++)
{
scanf("%d%d%d",&a,&b,&c);
if(c<map[a][b])
map[a][b] = map[b][a] = c;
}
for(int i = 1; i <= S; i++)
{
scanf("%d",&Scity[i]);
}
for(int i = 1; i <= D; i++)
{
scanf("%d",&Dcity[i]);
}
int mintime = INF;
for(int i = 1; i <= S; i++)
{
mintime = min(dijkstra(Scity[i]), mintime);
}
printf("%d\n",mintime);
}
}
用Bellman-Ford :
因为是无向图,所以边数有2*T条,改造成来回的有向图;
可以省略判断是否有负回路的代码;
#include <iostream>
#include <cstdio>
using namespace std;
#define maxn 1000
#define INF 0x3f3f3f3f
int Dcity[maxn];
int Scity[maxn];
int dis[maxn];
struct Edge
{
int a;
int b;
int weight;
}edge[2*maxn];
void relax(int u, int v, int weight) //松弛
{
if(dis[v] > dis[u] + weight)
dis[v] = dis[u] + weight;
}
void InIt(int V, int S) //初始化
{
for(int i = 1; i <= V; i++) //memset(dis,0x3f,sizeof(dis));
{
dis[i] = INF;
}
dis[S] = 0;
}
void Bellman_Ford(int V, int E, int S)
{
InIt(V,S);
for(int i = 1; i < V; i++)
{
for(int j = 1; j <= E; j++)
{
relax(edge[j].a,edge[j].b,edge[j].weight);
}
}
//for(int i= 1; i <= E; i++)
//{
// if(dis[edge[i].b] > dis[edge[i].a] + edge[i].weight)
// return false;
//}
//return true;
}
int main( )
{
int T,S,D;
while(scanf("%d%d%d",&T,&S,&D)!=EOF)
{
int num = 0;
for(int i = 1; i <= T; i++)
{
scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].weight);
edge[i+T].a = edge[i].b; //因为是无向图
edge[i+T].b = edge[i].a; //所以改成双向有向边
edge[i+T].weight = edge[i].weight; //权值相等
num = max(num,max(edge[i].a,edge[i].b)); //求出最大点的标号,节省Bellman_ford时间
}
for(int i = 1; i <= S; i++)
{
scanf("%d",&Scity[i]);
}
for(int i = 1; i <= D; i++)
{
scanf("%d",&Dcity[i]);
}
int mintime = INF;
for(int i = 1; i <= S; i++)
{
Bellman_Ford(num,2*T,Scity[i]);
for(int j = 1; j <= D; j++)
{
if(dis[Dcity[j]] < mintime)
mintime = dis[Dcity[j]];
}
}
printf("%d\n",mintime);
}
return 0;
}