题目链接http://ac.jobdu.com/problem.php?
pid=1411
转载请注明本文链接http://blog.csdn.net/yangnanhai93/article/details/41315349
这个题目,好难……
这个题目是自己瞎搞弄出来的答案。不知道有没有更优的方法,可是。也说下自己的思路好了
首先明白题目要求。要先从点s出发,然后最短的回到s的路径。所以必定有两种情况
1:出发之后回不来
2:出发之后回来
好吧。确实有点废话,如果第一个到的点为t
则1和2的情况都是求t到s的最短路径,所以仅仅要把从s能达到的点都求一遍最短路径就能够了
可是本题须要注意的问题是
1:在给的有向图中,即边会反复,所以要求一个最短的保存在邻接矩阵中
2:这也是最大的bug。居然会有s-s的边,这种话,採用上面的方法就会有点瑕疵了,由于上面的方法会算两遍,所以要先找到可能,把该值作为最短的初始化的值
#include <stdio.h> #include <memory.h> using namespace std; int n,m,s,A[501][501],x,y,z; bool visited[501]; int INF=2146483647; int dfs(int x,int s,int n) { int dis[501]; for(int i=1;i<=n;i++) { dis[i]=A[x][i]; visited[i]=false; } visited[x]=true; int u=x; for (int i=2;i<=n;i++) { int minDis=INF; for (int j=1;j<=n;j++) { if(!visited[j]&&dis[j]<minDis) { minDis=dis[j]; u=j; } } visited[u]=true; for (int j=1;j<=n;j++) { if(!visited[j]) { if(A[u][j]!=INF&&minDis!=INF&&dis[j]>A[u][j]+minDis) dis[j]=A[u][j]+minDis; } } } if(dis[s]==INF) dis[s]=-1; return dis[s]; //for(int i=1;i<) } int min_num(int x,int y) { return x>y?y:x; } int main() { //freopen("data.in","r",stdin); while(scanf("%d%d%d",&n,&m,&s)!=EOF) { int result=INF; for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) A[i][j]=INF; for (int i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); if(z<A[x][y]) { A[x][y]=z; if(x==y&&s==y&&result>z) result=z; } } for(int i=1;i<=n;i++) { if(A[s][i]!=INF) { int t=dfs(i,s,n); if(t!=-1) result=min_num(result,A[s][i]+t); } } if(result!=INF) printf("%d ",result); else printf("help! "); } return 0; } /************************************************************** Problem: 1411 User: vincent_ynh Language: C++ Result: Accepted Time:710 ms Memory:2000 kb ****************************************************************/