标题
个人笔记 ,关键路径例题理解
个人思路:额外建立一个dis数组,对每一个点的数值不断放缩,到最后初始点会是最优解。
//一直向前更新
dis数组更新
#include <bits/stdc++.h>
using namespace std;
struct node
{
int u,v,t;
} edge[50005];//储存点的坐标和两点之间的值。
int dis[50001];//储存每个点的值,并不断放缩。
int in[50001];//记录入度点
int out[50001];//记录出度点
int path[50001];//记录上个的入读点,用于比较相同出度点,保留入读点较小的点。
int ans;//记录起点;
void search(int n,int m)
{
memset(path,0,sizeof(path));
memset(dis,0,sizeof(dis));
for(int i=2; i<=n; i++)
{
bool flag=false;//判断是否全部更新完成。
for(int j=1; j<=m; j++)
{
if((dis[edge[j].u]<dis[edge[j].v]+edge[j].t)||((dis[edge[j].u]==dis[edge[j].v]+edge[j].t)&&(edge[j].v<path[edge[j].u])))
{
dis[edge[j].u]=dis[edge[j].v]+edge[j].t;
path[edge[j].u]=edge[j].v;//保留本次入读,便于相同点比较。
flag=true;
}
}
if(!flag)
{
break;
}
}
printf("%d\n",dis[ans]);
int k=ans;//从初始点开始,一直到zhongdian。
while(path[k])
{
printf("%d %d\n",k,path[k]);
k=path[k];
}
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(edge,0,sizeof(edge));
for(int i=1; i<=m; i++)
{
int u,v,t;
scanf("%d%d%d",&u,&v,&t);
edge[i].u=u;
edge[i].v=v;
edge[i].t=t;
in[v]++;//入度保存
out[u]++;//出度保存
}
for(int i=1; i<=n; i++)
{
if(in[i]==0)
{
ans=i;//寻找初始点。
}
}
search(n,m);
}
return 0
}
。。。
。