5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1
1 -1
这里首先提示大家:数组不要开的不恰当,我是TLE了几发,感觉心累。。。数组开小了不给RE给TLE。。。。真是够了。。。。
题目大意:(重点是单向图)
这里有n个车站,有m条路径,s是希望到达的终点(朋友的家),题干中一句:directed ways表示的是单向图,只能由车站a到车站b而不能从车站b开到车站a.(虽然题意是这样的,但是解题思路却是要改变这个定论的).
这里我直接想到的方法还是简洁无脑的floyd做法,但是想了想1000个点绝壁不能floyd啊,但是可以尝试优化一下啊。然后小小的优化了一下,还是超时了,然后就默默的滚去找dijkstra的模板了。。。我作为一个智商比较低的孩纸,还是天真的尝试了一下用起点车站每一次都dijkstra,然后找到最小值。结果还是依旧的口怕。。。。。。。。。。。。。
这个时候就要想了,我有多起点是动态给出的,但是终点却是定点,机智的我这个时候用终点去找起点的最近路,秒掉了问题:
#include<stdlib.h> #include<string.h> #include<stdio.h> using namespace std; #define MAX(a,b) (a > b ? a : b) #define MIN(a,b) (a < b ? a : b) #define MAXN 10000001 #define INF 1000000007 int w[1010][1010]; int d[1010]; int vis[1010]; int qidian[1010]; int n,m,zongdian; void dijkstra(int s)//dijkstra模板模板模板~~~~~~~~~~~。 { d[s]=0; for(int k=1;k<=n;k++) { int m=INF; for(int i=1;i<=n;i++) { if(!vis[i] && d[i]<=m) m=d[s=i]; } vis[s] = 1; for(int i=1;i<=n;i++) { d[i]=MIN(d[i],d[s]+w[s][i]); } } } int main() { while(~scanf("%d%d%d",&n,&m,&zongdian)) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { d[i]=INF; for(int j=1;j<=n;j++) { w[i][j]=INF; } } for(int i=0;i<m;i++) { int x,y,dis; scanf("%d%d%d",&x,&y,&dis); if(w[y][x]>dis)//注意是单向图,这个时候我要用终点找起点,所以是yx w[y][x]=dis; } dijkstra(zongdian);//拿终点去找起点。 /* for(int i=1;i<=n;i++) { printf("%d ",d[i]); } printf("\n");*///测试数据专用~~~~~~~~~~~~~ int q; int output=INF; scanf("%d",&q); for(int i=0;i<q;i++) { scanf("%d",&qidian[i]); if(d[qidian[i]]<output)output=d[qidian[i]]; } if(output==INF){printf("-1\n");continue;} printf("%d\n",output); } }