题目连接 http://acm.hust.edu.cn/vjudge/contest/123674#problem/C
题目大意是求从n到1的最短路径,这一题确实折腾的我好惨,首先题目都没看清楚,先入为主,题目先输入的是 t 然后才是 n.
其次memset 初始非零数组时可能会有问题,特别是二维数组,所以二维数组初始化的时候最好老老实实用二重循环吧!
很多现实中的情况点都是从1 开始的,而循环的时候又从0 开始,有时候很容易忽略,最好就是输入点的时候直接减一。。
一直编译错误,到头来发现做题目做傻了,数组的个数只能是常数这个都忘了,还弄了好久才明白过来,静静的哭一会吧。。
这题用书上的 模板就可以了,但有很多细节值得注意。这也提醒了我自己基础不好,一点小小的变动对我来说就是一个坑,
还是要脚踏实地。
#include<iostream> #include<cstdio> #include<cstring> #include<climits> #include<cmath> using namespace std; const int INF=INT_MAX/2;//INT_MAX 的头文件是#include<climits> 而且这样的表达式最好用const #define MA 1005 //宏定义不要有逗号!!!! //const 是值传递,而#define是表达式传递,可能会出错 int w[MA][MA]; int d[MA],v[MA]; int main() { int n,t; while(scanf("%d %d",&t,&n)!=EOF)//看清题 { for(int i=0;i<n;i++) for(int j=0;j<n;j++) w[i][j]=INF; //此处不要用memset,结果真是乱七八糟 int a,b,c; while(t--) { scanf("%d %d %d",&a,&b,&c); a=a-1; b=b-1; if(c<w[a][b])//路有多条时,求最短路径有效的就是最短的哪一条 w[a][b]=w[b][a]=c;//路是双向的 } memset(v,0,sizeof(v));//模板 for(int i=0;i<n;i++) d[i]=(i==n-1?0:INF);//不要忘了这里是n-1,粗心的人真是伤不起 for(int i=0;i<n;i++) { int x,m=INF; for(int y=0;y<n;y++) if(!v[y]&&d[y]<=m) m=d[x=y]; v[x]=1; for(int y=0;y<n;y++) d[y]=min(d[y],d[x]+w[x][y]); } printf("%d ",d[0]); //printf("%d",INF); } return 0; }
附上模板
//这个模板真的是看了我好久,真的很简洁 memset<v,0,sizeof(v);//清楚所有点的标号 for(int i=0;i<n;i++) d[i]=(i==0?0:INF);//此处的0代表的是起点 for(int i=0;i<n;i++) { int x,m=INF; for(int y=0;y<n;y++) if(!v[y]&&d[y]<=m) m=d[x=y];//找出离正在遍历的点最近的点 v[x]=1; for(int y=0;y<n;y++) d[y]=min(d[y],d[x]+w[x][y]);//更新d值,d是该点到起点的距离 }