<p>最短路径 </p><p>Time Limit: 1000 MS Memory Limit: 32767 K </p><p>Total Submit: 208(28 users) Total Accepted: 31(20 users) Rating: Special Judge: No Description 给出一个有向带权图G,针对该图有如下的两种操作: (1)标记该图的一个点 (2)找到两点间的只通过已标记点的最短路径长度</p><p> 输入: 输入包括多组测试,每组测试中第一行包括三个整数N,M,Q,N表示图中的节点数量,N<=300, M表示边的数量,M<=100000;Q表示执行多少次操作,Q<=100000,所有点被编号为0,1,2,...,N-1, 最初所有的点都是未标记的,接下来M行每行包括三个整数x,y,c,表示从x到y有一条边长度为c,c>0,然 后为Q行,每行表示一次操作,0 x表示将点x标记,1 x y表示查找x到y的只通过已标记点的最短路径长度, N=M=Q=0是输入结束。</p><p> 输出:</p><p> 输出以一行"Case #:"开始,#表示为第几组测试,从1开始 对于0 x操作,如果x已经被标记过了,输出"ERROR! At point x". 对于1 x y操作,如果x或y没有被标记过,输出"ERROR! At path x to y",如果无法从x通过标记过的节 点到达y,输出"No such path",否则输出要求的最短路径长度,每组测试后有一个空行。 Input 输入包括多组测试,每组测试中第一行包括三个整数N,M,Q,N表示图中的节点数量,N<=300, M表示边的数量,M<=100000;Q表示执行多少次操作,Q<=100000,所有点被编号为0,1,2,...,N-1, 最初所有的点都是未标记的,接下来M行每行包括三个整数x,y,c,表示从x到y有一条边长度为c,c>0,然 后为Q行,每行表示一次操作,0 x表示将点x标记,1 x y表示查找x到y的只通过已标记点的最短路径长度, N=M=Q=0是输入结束。 </p><p> Output 输出以一行"Case #:"开始,#表示为第几组测试,从1开始 对于0 x操作,如果x已经被标记过了,输出"ERROR! At point x". 对于1 x y操作,如果x或y没有被标记过,输出"ERROR! At path x to y",如果无法从x通过标记过的节 点到达y,输出"No such path",否则输出要求的最短路径长度,每两组测试之间有一个空行。</p><p> </p><p> Sample Input 5 10 10 1 2 6335 0 4 5725 3 3 6963 4 0 8146 1 2 9962 1 0 1943 2 1 2392 4 2 154 2 2 7422 1 3 9896 0 1 0 3 0 2 0 4 0 4 0 1 1 3 3 1 1 1 0 3 0 4 0 0 0 Sample Output </p><p>Case 1: ERROR! At point 4 ERROR! At point 1 0 0 ERROR! At point 3 ERROR! At point 4</p><p> </p><p>要懂得floyd算法原理,对每个顶点 所有边都要松弛一遍,那么这是在所有边都可访问的情况下。对于这个题目,可以每次标记一个点,都以这个点为中心松弛所有边</p><p> </p><p>[cpp] view plaincopy </p>
#include<iostream> #include<string.h> using namespace std; const int INF=304; int G[INF][INF]; int vis[INF]; int main() { int n,m,q; int u,v,w,cse=1; while(cin>>n>>m>>q,n+m+q) { memset(G,0x1f,sizeof(G)); memset(vis,0,sizeof(vis)); for(int i=0; i<=n; i++) G[i][i]=0; for(int i=0; i<m; i++) { cin>>u>>v>>w; G[u][v]=G[u][v]>w?w:G[u][v]; } cout<<"Case "<<cse++<<":\n"; int x,y,z; for(int i=0; i<q; i++) { cin>>x; if(x) { cin>>y>>z; if(!vis[y]||!vis[z]) { cout<<"ERROR! At path "<<y<<" to "<<z<<endl; } else if(G[y][z]>=0x1f1f1f1f) { cout<<"No such path"<<endl; } else cout<<G[y][z]<<endl; } else { cin>>y; if(vis[y]) { cout<<"ERROR! At point "<<y<<endl; } else { vis[y]=1; for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(G[i][y]+G[y][j]<G[i][j]) { G[i][j]=G[i][y]+G[y][j]; } } } } } } cout<<endl; } return 0; }
原文地址:http://blog.csdn.net/lsgqjh/article/details/46572803