SDUTOJ 2498 the Key Path on the AOE network is the shortest path spfa, sdutojspfa
Description
A Directed Graph without loops is called a Directed Graph (DAG.
AOE (Activity On Edge) Network: as the name suggests, an Edge is used to represent the active network. Of course, it is also a DAG. Unlike AOV, the activity is represented on the edge, as shown in:
As shown above, there are 11 Activities (11 edges) and 9 events (9 vertices ). The entire project has only one start point and one completion point. That is, there is only one point with zero inbound (source point) and only one point with zero outbound (sink point ).
Key Path: The longest path length from the start point to the completion point. The path length is the time consumed by the edge activity. As shown in, 1 to 2 to 5 to 7 to 9 are key paths (there are more than one key path. Please output the smallest Lexicographic Order). The sum of weights is 18.
Input
There are multiple groups of data, so there must be no more than 10 groups, and there must be only one source point and sink point. Input a vertex number n (2 <= n <= 10000), edge number m (1 <= m <= 50000), and then input the start point sv, end point ev, weight w (1 <= sv, ev <= n, sv! = Ev, 1 <= w <= 20 ). Data ensures graph connectivity.
Output
The weight and value of the key path, and the path on the Key Path is output from the source point (if there are multiple, please output the smallest Lexicographic Order ).
Sample Input
9 111 2 61 3 41 4 52 5 13 5 14 6 25 7 95 8 76 8 48 9 47 9 2
Sample Output
181 22 55 77 9
Hint
In fact, a restriction is added to the longest path.
When I started using disktra, I changed the template and found that it was incorrect. If the array is not opened, it cannot be changed.
# Include <stdio. h> # define maxnum 1000 # define maxint 999999int dist [maxnum]; // the shortest path length from the current point to the source point int prev [maxnum]; // record the previous node of the current vertex int c [maxnum] [maxnum]; // record the path length between two points in the graph int n, line; // number of nodes and path in the graph void Dij (int n, int v, int * dist, int * prev, int c [maxnum] [maxnum]) // v indicates the source point? {Int s [maxnum] = {0}; // determines whether the point has been saved to the s array int I; for (I = n; I> = 1; I --) {dist [I] = c [v] [I]; // store the initial distance from the source vertex to the I vertex into the array dist s [I] = 0; // if (dist [I] = 0) is not used in initialization, // if the distance from the source point to the point is infinite, no connection point prev [I] = 0; else prev [I] = v;} dist [v] = 0; // The distance from the source point to the source point is initialized to 0 s [v] = 1; // store the source point to the array s // The nodes that are not put into the set s in sequence, take dist [] the minimum value of the node is put in // once s contains all vertices in v, dist records the shortest path from the source point to all other vertices. // note that it starts from the second node. The first node indicates the source point for (I = 2; I <= n; I ++) {int tmp = 0; int u = V; for (int j = n; j> = 1; j --) // find the dist of the currently unused vertex j [j] minimum value {if ((! S [j]) & dist [j]> tmp) {u = j; // The number of the smallest distance point in the current adjacent contact tmp = dist [j];} s [u] = 1; // after a for loop ends, we find the least distance among all unused points, save this point to the set s. // update the dist value for (int j = n; j> = 1; j --) {if ((! S [j]) & c [u] [j]> 0) // determines that the vertex is not added to the s set and the distance exists, that is, it goes through the {int newdist = dist [u] + c [u] [j]; // determine the distance between the vertex j and the distance from the vertex j if (newdist> dist [j]) {dist [j] = newdist; prev [j] = u ;}}}// find the path from source point v to destination u, and output void searc (int * prev, int v, int u) {int que [maxnum]; // The storage path of this array, int tot = 1; que [tot] = u; // start from the end, always locate the source vertex v and record the path tot ++; int tmp = prev [u]; while (tmp! = V) {que [tot] = tmp; tot ++; tmp = prev [tmp];} que [tot] = v; for (int I = tot; i> = 1; I --) // output {if (I! = 1) printf ("% d->", que [I]); else printf ("% d \ n", que [I]);} // note, if the output distance is required for the question, you can directly output dist [u]} int main () {scanf ("% d", & n, & line); int p, q, len; for (int I = 1; I <= n; I ++) {for (int j = 1; j <= n; j ++) c [I] [j] = 0;} for (int I = 1; I <= line; I ++) {dist [I] = 0 ;} for (int I = 1; I <= line; I ++) {scanf ("% d", & p, & q, & len ); if (len> c [p] [q]) {c [p] [q] = len; // c [q] [p] = len ;}} dij (n, 1, dist, prev, c); printf ("the shortest path length from the source point to the end point is % d \ n", dist [n]); searc (prev, 1, n); return 0 ;}
Below is the spfa Method
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<queue>#define INF 0x3f3f3f3fusing namespace std;struct node{ int u,v,w,next;} edge[500010];int cnt,n,m,head[10010],dis[10010],vis[10010],pre[10010], pre1[10005];int id[10005],cd[10005];void add(int u,int v,int len){ edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=len; edge[cnt].next=head[u]; head[u]=cnt++;}void spfa(int u,int v,int n){ memset(vis,0,sizeof(vis)); memset(pre,INF,sizeof(pre)); memset(dis,-INF,sizeof(dis)); queue<int>q; q.push(u); dis[u]=0; vis[u]=1; while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int p=head[x]; p!=-1; p=edge[p].next) { if(dis[edge[p].v]<dis[x]+edge[p].w||(dis[edge[p].v]==dis[x]+edge[p].w&&x<pre[edge[p].v])) { dis[edge[p].v]=dis[x]+edge[p].w; pre[edge[p].v]=x; if(!vis[edge[p].v]) { vis[edge[p].v]=1; q.push(edge[p].v); } } } } int k=0; printf("%d\n",dis[v]); for(int i=v; i!=INF; i=pre[i]) pre1[k++]=i; for(int i=1; i<k; i++) printf("%d %d\n",pre1[i-1],pre1[i]);}int main(){ while(~scanf("%d %d",&n,&m)) { int u,v,w; memset(head,-1,sizeof(head)); memset(id,0,sizeof(id)); memset(cd,0,sizeof(cd)); while(m--) { scanf("%d %d %d",&u,&v,&w); add(v,u,w); id[u]++; cd[v]++; } for(int i=1; i<=n; i++) { if(id[i]==0) u=i; if(cd[i]==0) v=i; } spfa(u,v,n); } return 0;}