DAG上的最长路。
如果使用floyd可以将所有边值取反,这样就转化成了最短路问题了。
用时0.176s。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #define MAXN 105 using namespace std; int main() { int n,s,kase=0; while(scanf("%d",&n)&&n) { int gl[MAXN][MAXN]; scanf("%d",&s); int p,q; memset(gl,0x7f,sizeof(gl)); int INF=gl[0][0]; while(scanf("%d%d",&p,&q)&&!(!p&&!q)) gl[p][q]=-1; for(int i=0; i<=n; ++i) gl[i][i]=0; for(int k=1; k<=n; ++k) for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) if(gl[i][k]<INF&&gl[k][j]<INF) gl[i][j]=min(gl[i][j],gl[i][k]+gl[k][j]); int ans=0,ed=0; for(int i=1; i<=n; ++i) if(gl[s][i]<ans) { ans=gl[s][i]; ed=i; } printf("Case %d: The longest path from %d has length %d, finishing at %d.\n",++kase,s,-ans,ed); printf("\n"); } return 0; }
用邻接矩阵实现的SPFA。
用时0.056s。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define MAXN 105 using namespace std; int main() { int n,s,kase=0; while(scanf("%d",&n)&&n) { int gl[MAXN][MAXN]= {0}; scanf("%d",&s); int p,q; while(scanf("%d%d",&p,&q)&&!(!p&&!q)) gl[p][q]=-1; for(int i=0; i<=n; ++i) gl[i][i]=0; int dis[MAXN]; memset(dis,0x7f,sizeof(dis)); int INF=dis[0]; queue<int> que; que.push(s); dis[s]=0; bool inq[MAXN]= {0}; inq[s]=true; while(!que.empty()) { int getfront=que.front(); que.pop(); for(int i=1; i<=n; ++i) { if(gl[getfront][i]&&dis[getfront]<INF&&dis[getfront]+gl[getfront][i]<dis[i]) { dis[i]=dis[getfront]+gl[getfront][i]; if(!inq[i]) { que.push(i); inq[i]=true; } } } inq[getfront]=false; } int ans=0,ed=0; for(int i=1; i<=n; ++i) if(dis[i]<ans) { ans=dis[i]; ed=i; } printf("Case %d: The longest path from %d has length %d, finishing at %d.\n",++kase,s,-ans,ed); printf("\n"); } return 0; }
最后这个是邻接表实现的SPFA。
用时0.038s。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define MAXN 105 using namespace std; struct Edge { int to,cost; Edge(int a,int b):to(a),cost(b) {} }; int main() { int n,s,kase=0; while(scanf("%d",&n)&&n) { vector<Edge> gl[MAXN]; scanf("%d",&s); int p,q; while(scanf("%d%d",&p,&q)&&!(!p&&!q)) gl[p].push_back(Edge(q,1)); int dis[MAXN]= {0}; queue<int> que; que.push(s); bool inq[MAXN]= {0}; inq[s]=true; while(!que.empty()) { int getfront=que.front(); que.pop(); for(int i=0; i<gl[getfront].size(); ++i) { int t=gl[getfront][i].to,w=gl[getfront][i].cost; if(dis[getfront]+w>dis[t]) { dis[t]=dis[getfront]+w; if(!inq[t]) { que.push(t); inq[t]=true; } } } inq[getfront]=false; } int ans=0,ed=0; for(int i=1; i<=n; ++i) if(dis[i]>ans) { ans=dis[i]; ed=i; } printf("Case %d: The longest path from %d has length %d, finishing at %d.\n",++kase,s,ans,ed); printf("\n"); } return 0; }
用Bellmanford可以直接改变松弛条件实现求最长路,floyd似乎不行,得将权值取反转化成最短路求解。