题意:给你一些机器指令,某些有先后顺序(若A->B,C->B则必须A、C执行完才能执行B),且有安全距离(若A->B 距离n)那么必须在从A执行算起n时间,才能执行B,一次可以运行多个指令,指令的完成只花费1,最后求执行完所有指令所需的最短的时间。
思想:求到达各点的最大值(所有能到达该点的花费的最大值)的最大值(即所有点的最大值)。
解法:①纯递归搜索:这是最简单直观的做法,从入度为0点开始搜索,记录每点的最大值,最后求所有点的最大值即可。
② “最短路算法”求解:你可以直接求所有点的最长路或者是反向建图求最短路 ,最后找最长的或者最短的(注意负数)。
③用拓扑排序的思想也可求解。
这么所方法其实都一样,代码的实现可能与叙述有所不同,但思想绝对一样!
①的代码:
#include <stdio.h> #include <string.h> #define N 1002 #define M 10002 int nodev[N]; int nodeu[M],value[M],next[M]; int indegree[N]; void Build_Graph(int m) { int i,v,u,val,ind; memset(indegree,0,sizeof(indegree)); memset(nodev,-1,sizeof(nodev)); ind=0; for(i=0;i<m;i++) { scanf("%d %d %d",&v,&u,&val); indegree[u]++; nodeu[ind]=u; value[ind]=val; next[ind]=nodev[v]; nodev[v]=ind; ind++; } } int record[N]; int DFS(int v) { int i,u,val; if(record[v]!=0) { return record[v]; } for(i=nodev[v];i!=-1;i=next[i]) { u=nodeu[i]; val=DFS(u); if(val+value[i]>record[v]) record[v]=val+value[i]; } return record[v]; } void solve() { int v,n,m,temp,max; while(scanf("%d %d",&n,&m)!=EOF) { Build_Graph(m); memset(record,0,sizeof(record)); max=0; for(v=0;v<n;v++) { if(indegree[v]==0) { temp=DFS(v); if(temp>max) max=temp; } } printf("%d\n",max+1); } } int main() { solve(); return 0; }
②思想的代码:
#include <stdio.h> #include <string.h> #define N 1002 #define M 10002 #define MOVE(x) (x=(x+1)%N) #define MAXVAL 0xfffffff int S,E; //添加的源点,终点 int nodev[N]; int nodeu[M+N*2],value[M+N*2],next[M+N*2],ind; void addedge(int v,int u,int val) { nodeu[ind]=u; value[ind]=val; next[ind]=nodev[v]; nodev[v]=ind; ind++; } void Build_Graph(int n,int m) { int i,v,u,val; memset(nodev,-1,sizeof(nodev)); S=0; E=n+1; ind=0; for(i=0;i<m;i++) { scanf("%d %d %d",&v,&u,&val); v++; u++; val=-val; addedge(u,v,val); } for(i=1;i<=n;i++) { addedge(S,i,0); addedge(i,E,0); } } int queue[N],dist[N]; bool flag[N]; void SPFA(int s,int n) { int i,v,u,val; int front,rear; for(i=1;i<=n+1;i++) dist[i]=MAXVAL; dist[s]=0;//当S加入队列时,一定有负环,但有负环,不一定是S一定要进队列!! memset(flag,false,sizeof(flag)); front=-1; rear=-1; queue[MOVE(rear)]=s; flag[s]=true; //可不要 // for(i=nodev[s];i!=-1;i=next[i]) // { // u=nodeu[i]; val=value[i]; // dist[u]=val; // queue[MOVE(rear)]=u; flag[u]=true; // } while(front!=rear) { v=queue[MOVE(front)]; flag[v]=false; for(i=nodev[v];i!=-1;i=next[i]) { u=nodeu[i]; val=value[i]; if(dist[v]+val<dist[u]) { dist[u]=dist[v]+val; if(!flag[u]) { queue[MOVE(rear)]=u; flag[u]=true; } } } } } void solve() { int n,m; while(scanf("%d %d",&n,&m)!=EOF) { Build_Graph(n,m); SPFA(S,n); printf("%d\n",1-dist[E]); } } int main() { solve(); return 0; }