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 ",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 ",mintime); } return 0; }