关键路径(CRITICALPATH 邻接表建图)

# include<iostream>
# include<queue>
# include<cstring>
# include<stack>
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;
queue<int> q;  //存放入度为0的顶点索引 
stack<int> ss; //存放拓扑排序的逆序列 
int indegree[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;
	}
	
}
void findindegree(graph g)
{
	for(int i=0;i<g.vertexnum;i++)
	 {
	 	for(int j=0;j<g.vertexnum;j++)
	 	{
	 	   if(i!=j)
			{
	 	  		 arcnode* s=g.vertexs[j].firstarc;
				while(s)
				{
					if(s->adjnode==i)
					 {
				 		indegree[i]++;
				 		break;
				 	}
					s=s->nextarc;
				}	
	 		}
		 }
	 }
}
bool topulogical(graph g)
{
	int cnt=0;
	for(int i=0;i<g.vertexnum;i++)
	{
		if(!indegree[i])   //入度为0的入队列 
		  q.push(i);
		ve[i]=0;   //初始化事件最早开始时间 
	}
	while(!q.empty())
	{
		int k=q.front();
		q.pop();
		ss.push(k);
		cnt++;
		arcnode* s=g.vertexs[k].firstarc;
		while(s)
		{
			int j=s->adjnode; 
			indegree[j]--;
			if(!indegree[j])
			  q.push(s->adjnode);
			if(ve[k]+s->weight>ve[j])   //松弛 
			   ve[j]=ve[k]+s->weight;  
			s=s->nextarc;
		}
		
	}
	if(cnt<g.vertexnum)
	  return false;
	return true;
}
void criticalpath(graph g)
{
	if(!topulogical(g))
	{
		cout<<"存在回路"<<endl;
	    return ;	 
	 } 
	for(int i=0;i<g.vertexnum;i++)
	{
	vl[i]=ve[g.vertexnum-1];   //初始化事件最迟开始时间,等于汇点的最早开始时间,
	                           //当然除汇点以外的点的最迟开始时间也可初始化为某一最大值	
	}
	while(!ss.empty())
	{
		int k=ss.top();
		ss.pop();
	   arcnode *s=g.vertexs[k].firstarc;
	   while(s)
	   {
	   	int j=s->adjnode;
	   	if(vl[j]-s->weight<vl[k])
	   	  vl[k]=vl[j]-s->weight;
	   	s=s->nextarc;
	     }
	}
	for(int j=0;j<g.vertexnum;j++)
		{
			arcnode *s=g.vertexs[j].firstarc;
			while(s)
			{
			 	int k=s->adjnode;
			 	int w=s->weight;
			 	int ee=ve[j];
			 	int el=vl[k]-w;
			 	if(ee==el)
			 	  cout<<"V"<<g.vertexs[j].data<<"->"<<"V"<<g.vertexs[k].data<<"dis"<<w<<" "<<endl;
				s=s->nextarc; 	
		   }
		}
 } 
int main()
{
	graph g;
	init(g);
	memset(indegree,0,sizeof(indegree));
	findindegree(g);
	criticalpath(g);
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值