关键路径criticalpth(dfs)

# include<iostream>
# include<queue>
# include<cstring>
# include<stack>
# include<vector>
using namespace std;
const int maxn=100+5;
typedef struct arcnode{
	int adjnode;
	int weight;
	arcnode *nextarc;
}arcnode;
typedef struct vnode{   
   int data; 
	arcnode *firstarc;
}vnode;
typedef struct graph{
	vnode vertexs[maxn];
	int vertexnum;  //顶点数目 
	int edgenum;   //边数目 
}graph;
vector<int> ww;//存放拓扑排序的序列  使用vector既可以存放拓扑排序的序列,也可就拓扑逆序列 
              //当然也可使用栈去存放拓扑序列用队列去存放拓扑逆序列 (注意dfs先出来的顶点是出度为0的顶点)  
int vis[maxn];  //顶点标记
 
int ve[maxn];//事件最早发生时间 
int vl[maxn];// 事件最迟发生时间 
int  e[maxn];//活动最早发生时间
int  l[maxn];//活动最迟发生时间 
int find(graph g,int v)
{
	for(int i=0;i<g.vertexnum;i++)
	 {
	 	if(g.vertexs[i].data==v)
	 	  return i;
	 }
	
}
void init(graph &g)
{
	cin>>g.vertexnum>>g.edgenum;
	for(int i=0;i<g.vertexnum;i++)
	{
		cin>>g.vertexs[i].data;
		g.vertexs[i].firstarc=NULL;
	}
	 int u,v,w;
	for(int i=0;i<g.edgenum;i++)
	{
		cin>>u>>v>>w;
		arcnode *s=new arcnode();
		int index_u=find(g,u);
		int index_v=find(g,v);
		s->adjnode=index_v;
		s->weight=w;
		s->nextarc=g.vertexs[index_u].firstarc;
		 g.vertexs[index_u].firstarc=s;
	}
	
}
bool dfs(int i,graph g)
{
	vis[i]=-1;
	arcnode *s=g.vertexs[i].firstarc;
	while(s)
	{
		if(vis[s->adjnode]<0)   //表示有回路 
		   return false;
		if(!vis[s->adjnode]&&!dfs(s->adjnode,g))  
		   return false;
		s=s->nextarc;
	}
	vis[i]=1;
	ww.push_back(i);  //逆序列 
	return true;
}
bool topulogicalsort(graph g)
{
	 
	for(int i=0;i<g.vertexnum;i++)
	 {
	 	ve[i]=0;    //初始化事件最早时间为0; 
	   if(!vis[i])
	  	{
	  		if(!dfs(i,g))
	  	 		 {
	  	  			return false;
					}
	 		 }
    	}
    for(vector<int>::iterator in=ww.end()-1;in!=ww.begin()-1;in--)
    {
    	int k=*in;
    	arcnode *s=g.vertexs[k].firstarc;
    	while(s)
    	{
    	    int j=s->adjnode;
			if(ve[j]<ve[k]+s->weight)
			   ve[j]=ve[k]+s->weight;	
    		s=s->nextarc;
		  }
	  }  
	  
	    return true;
}
void criticalpath(graph g)
{
	if(!topulogicalsort(g))
	{
		cout<<"存在回路"<<endl;
		return ;
	}
	for(int i=0;i<g.vertexnum;i++)
	   vl[i]=ve[g.vertexnum-1];    //初始化最迟开始时间 
	for(vector<int>::iterator in=ww.begin();in!=ww.end();in++)
	{
		int k=*in;
		arcnode *s=g.vertexs[k].firstarc;
		while(s)
		{
			int j=s->adjnode;
			if(vl[k]>vl[j]-s->weight)
			    vl[k]=vl[j]-s->weight;
			s=s->nextarc;
		}
	}
	for(int i=0;i<g.vertexnum;i++)
	{
		arcnode *s=g.vertexs[i].firstarc;
		while(s)
		{
			int j=s->adjnode;
			int e=ve[i];
			int l=vl[j]-s->weight;
			if(e==l)
			{
				cout<<"V"<<g.vertexs[i].data<<"->"<<"V"<<g.vertexs[j].data<<"dis:"<<s->weight<<endl; 
				
			}
			s=s->nextarc;
		}
		
	}
	
}
int main()
{
	graph g;
	init(g);
	memset(vis,0,sizeof(vis));
	criticalpath(g);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值