注意将后一个数插到前一个数上,然后用队列每次存储入度为0的数,累加同一工资级别的人的工资

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10005
typedef struct node //邻接表节点
{
int adj; //节点值
struct node * next;
}node;
struct //顶点
{
int in; //入度
node * next;
}v[N];
int visited[N], queue[N], front, rear;
void insert(int x, int y) //尾插法将y指向x
{
node * p = (node *)malloc(sizeof(node));
p->adj = x;
p->next = v[y].next;
v[y].next = p;
v[x].in++; //x的入度增加
}
void topo(int x) //清空队列中存的入度为0的数
{
if(v[x].next == NULL)
return;
node * p = v[x].next;
while(p)
{
v[p->adj].in--; //x点指向的点的入度--
p = p->next; //指向邻接表的下一个节点
}
v[x].next = NULL; //将v[x]节点指向空,表示与x之间存在弧的点都已经清空
}
int main()
{
int n, m;
while(scanf("%d%d", &n, &m)!=EOF)
{
rear = front = 0; //队头队尾置0
memset(visited, 0, sizeof(visited));
memset(v, 0 , sizeof(v));
int sum = 0, flag = 0, base = 888;
int i, j, a, b, sign;
for(i = 0; i < m; i++)
{
scanf("%d%d", &a, &b);
insert(a, b); //将a插到b的表上,即使b指向a
}
for(j = 0; j < n;)
{
sign = 0;
for(i = 1; i <= n; i++)
{
if(v[i].in == 0 && !visited[i])
{
visited[i] = 1; //标记i点已遍历过
sign = 1; //标记,如果sign = 0 说明没有入度为0的点即存在回路
queue[rear++] = i;//将入度为0的数存入队列
}
}
if(!sign)
{
flag = 1;
break;
}
while(front < rear) //遍历队列内的元素,并求出sum
{
topo(queue[front++]); //从队列头开始往后找
j++; //统计已经遍历过的节点数
sum += base; //求和
}
base++;
}
if(flag) printf("-1\n");
else printf("%d\n", sum);
}
return 0;
}