#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#define MAXSIZE 101
#define COMMIT
typedef struct ArcNode
{
int adjvex = 0;
int weight = 0;
struct ArcNode* next = NULL;
}ArcNode_t;
typedef struct Vex
{
ArcNode_t* firstarc = NULL;
int incount = 0;
}Vex_t;
typedef struct AGraph
{
Vex_t vexs[MAXSIZE];
int n = 0, e = 0;
}AGraph_t;
typedef struct stack
{
int st[MAXSIZE];
int front = 0;
int rear = 0;
}Stack_t;
void Push(Stack_t* s, int data)
{
if ((s->front + 1) % MAXSIZE == (s->rear) % MAXSIZE)
{
//cout << "Push error: stack is full!" << endl;
return;
}
s->front = (s->front + 1) % MAXSIZE;
s->st[s->front] = data;
//cout << "push:" << data << endl;
}
int Pop(Stack_t* s, int* pop)
{
if ((s->front) % MAXSIZE == (s->rear) % MAXSIZE)
{
//cout << "Pop error: stack is empty!" << endl;
return -1;
}
else
{
int data = s->st[s->front];
s->front = (s->front - 1) % MAXSIZE;
*pop = data;
//cout << "pop " << data << endl;
return 0;
}
}
int CreateAGraph(AGraph* A)
{
int* n = &(A->n);
int* e = &(A->e);
Vex_t* vexs = (A->vexs);
#ifdef COMMIT
cin >> *n >> *e;
#else
ifstream infile("data.in");
while (!infile.eof())
{
infile >> *n >> *e;
cout << "n=" << *n << endl;
cout << "e=" << *e << endl;
#endif
for (int i = 0; i < *e; i++)
{
int a = 0, b = 0, wgh = 0;
#ifdef COMMIT
cin >> a >> b >> wgh;
#else
infile >> a >> b >> wgh;
//1.a,b,weight,
//2.incount,arc->arc
cout << "(" << a << " ," << b << ") = " << wgh << endl;
#endif
ArcNode_t* arc = (ArcNode*)malloc(sizeof(ArcNode_t));
ArcNode_t* p = vexs[a].firstarc;
arc->next = p;
vexs[a].firstarc = arc;
arc->adjvex = b;
arc->weight = wgh;
vexs[b].incount++;
}
#ifdef COMMIT
#else
}
infile.close();
#endif
return 0;
}
int TopSort(AGraph_t* A, int* ve, int* vl)
{
int e = A->e;
int n = A->n;
Vex_t* vexs = A->vexs;
Stack_t st1;
Stack_t st2;
int i = 1;
for (i = 1; i <= A->n; i++)
if (vexs[i].incount == 0)
{
ve[i] = 0;
Push(&st1, i);
Push(&st2, i);
}
int pop = 0;
while (Pop(&st1, &pop) != -1)
{
ArcNode_t* p = vexs[pop].firstarc;
while (p != NULL)
{
vexs[p->adjvex].incount--;
if (vexs[p->adjvex].incount == 0)
{
Push(&st1, p->adjvex);
Push(&st2, p->adjvex);
}
//get ve[]
if (ve[p->adjvex] < (ve[pop] + p->weight))
ve[p->adjvex] = ve[pop] + p->weight;
p = p->next;
}
}
//get vl[]
int maxdist = 0;
for (int i = 1; i <= n; i++)
maxdist = ve[i] > maxdist ? ve[i] : maxdist;
cout << maxdist << endl;//zzz
for (int i = 1; i <= A->n; i++)
vl[i] = maxdist;
while (Pop(&st2, &pop) != -1)
{
ArcNode_t* p = vexs[pop].firstarc;
while (p != NULL)
{
if (vl[pop] > vl[p->adjvex] - p->weight)
vl[pop] = vl[p->adjvex] - p->weight;
p = p->next;
}
}
#ifndef COMMIT
for (int i = 1; i <= A->n; i++)
{
cout << i << " : ve=" << ve[i] << " \tvl=" << vl[i] << endl;
}
#endif
return 0;
}
void CriticalPath(AGraph_t* A, int* ve, int* vl, int* ee, int* el)
{
int* n = &(A->n);
int* e = &(A->e);
Vex_t* vexs = A->vexs;
int k = 0;//edge seq
for (int i = 1; i <= *n; i++)
{
ArcNode_t* p = vexs[i].firstarc;
while (p != NULL)
{
k++;
ee[k] = ve[i];
el[k] = vl[p->adjvex] - p->weight;
if (ee[k] == el[k])
cout << i << "->" << p->adjvex << endl;
p = p->next;
}
}
#ifndef COMMIT
for (int i = 1; i <= A->e; i++)
{
cout << i << " : ee=" << ee[i] << " \tel=" << el[i] << endl;
}
#endif // !COMMIT
}
int main()
{
AGraph_t A;
if (CreateAGraph(&A) != 0)return 0;
int ve[MAXSIZE] = { 0 }, vl[MAXSIZE] = { 0 };
int* ee = (int*)malloc(sizeof(int) * A.e);
int* el = (int*)malloc(sizeof(int) * A.e);
TopSort(&A, ve, vl); //get ve vl
CriticalPath(&A, ve, vl, ee, el);//get ee el
//free(ee);
//free(el);
}
7 8
3 1 1
3 2 2
1 4 4
2 4 3
4 6 2
4 7 2
6 5 2
7 5 2
6 5
1 3 1
2 3 1
3 4 1
4 5 1
4 6 2