Sicily 1031 Campus(单源最短路Dijkstra)

//邻接矩阵Dijkstra,得开始学用邻接表的方式来处理单源最短路问题 可以把复杂度提高到O(ElgE) //学会了map关联容器,十分强大的类 #include #include #include #include//关联容器 using namespace std; const int INF = 1000000;//定义无穷,注意不能太大,否则在更新结点过程中可能产生溢出 int G[205][205];//100条边最多只有200个结点 int dis[205]; bool flag[205]; int t,road,d,n; string start,end; int dijkstra(int a,int b)//Dijkstra处理从起点a到b的最短路 { memset(flag,0,sizeof(flag)); for(int i = 0;i < n;++i) dis[i] = (i == a ? 0 : INF);//初始化dis数组,起点应初始化为0 for(int i = 0;i < n;++i) { int _min = INF,x = a;//对标号变量的初始化应该是起点a for(int y = 0;y < n;++y) { if(!flag[y] && dis[y] < _min)//从未标号结点中选出dis最小的结点x { _min = dis[y]; x = y; } } flag[x] = 1;//标记x for(int y = 0;y < n;++y) dis[y] = min(dis[y],dis[x] + G[x][y]);//更新从x出发到其他点的距离 } if(flag[b])//如果终点是有标号结点,则证明a点到b点是连通的 return dis[b];//返回dis值 else return -1; } int main() { //freopen("in.txt","r",stdin); cin >> t; while(t--) { cin >> road; for(int i = 0;i < 205;++i) for(int j = 0;j < 205;++j) G[i][j] = (i == j ? 0 : INF); map edge_map;//利用关联容器处理名字到图结点编号的转化 n = 0; for(int i = 0;i < road;++i) { cin >> start >> end >> d; { if(!edge_map.count(start))//如果从来没出现过这个结点 { edge_map[start] = n++;//为这个结点定义一个标号 } if(!edge_map.count(end)) { edge_map[end] = n++; } G[edge_map[start]][edge_map[end]] = G[edge_map[end]][edge_map[start]] = d;//无向图双向联通 } } cin >> start >> end; if(start == end)//名字相同时返回0,即使不存在这个点……没见过这么扑街的条件,害我WA了N次 cout << 0 << endl; else if(!edge_map.count(start) || !edge_map.count(end))//其中有一个点的边不存在,返回不可达 cout << -1 << endl; else cout << dijkstra(edge_map[start],edge_map[end]) << endl; } return 0; }  

你可能感兴趣的:(图论)