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
从起点往终点找要多次调用函数,很容易超时~所以需要反着来~~只调用一次函数~~而且还要注意的是。。。路径是单向的~~
AC-code:
Dijkstra:
#include<cstdio> #define max 0x3f3f3f3f #define min(a,b) (a>b?b:a) int n,dis[1005],cost[1005][1005]; void dijkstra(int a) { int vis[1005],i; for(i=1;i<=n;i++) { dis[i]=max; vis[i]=0; } dis[a]=0; while(1) { int v=-1; for(i=1;i<=n;i++) if(!vis[i]&&(dis[i]<dis[v]||v==-1)) v=i; if(v==-1) break; vis[v]=1; for(i=1;i<=n;i++) dis[i]=min(dis[i],dis[v]+cost[v][i]); } } int main() { int so[1005],m,s,i,j,a,b,c; while(~scanf("%d%d%d",&n,&m,&s)) { int ans=max; for(i=1;i<=n;i++) for(j=1;j<=n;j++) cost[i][j]=max; while(m--) { scanf("%d%d%d",&a,&b,&c); cost[b][a]=min(cost[b][a],c); } scanf("%d",&a); dijkstra(s); for(i=0;i<a;i++) { scanf("%d",&b); ans=min(ans,dis[b]); } if(ans==max) printf("-1\n"); else printf("%d\n",ans); } return 0; }
SPFA:
#include<cstdio> #include<queue> #include<cstring> #define INF 0x3f3f3f3f using namespace std; int num,dis[1005],vis[1005],head[20005*2]; struct node { int from,to,val,next; }A[20005*2]; void chan(int a,int b,int c) { node e={a,b,c,head[a]}; A[num]=e; head[a]=num++; } void spfa(int sx) { queue<int>q; memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); q.push(sx); vis[sx]=1; dis[sx]=0; while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=A[i].next) { int v=A[i].to; if(dis[v]>dis[u]+A[i].val) { dis[v]=dis[u]+A[i].val; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main() { int n,m,s,p,q,t,w; while(~scanf("%d%d%d",&n,&m,&s)) { num=0; memset(head,-1,sizeof(head)); while(m--) { scanf("%d%d%d",&p,&q,&t); //chan(p,q,t);路径是单向的~~~ chan(q,p,t); } spfa(s); scanf("%d",&w); int min=INF; while(w--) { scanf("%d",&p); if(min>dis[p]) min=dis[p]; } if(min==INF) printf("-1\n"); else printf("%d\n",min); } return 0; }