#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
int n,m,num=0,top,mop;
int chudu[1005],tp[1005][1005],rudu[1005],t[1005],bo[1005],mp[1005];
struct sd{
int c;//表示状态
int u;//表示阈值
}ms[1005];
//ms是输入的节点,tp是存边即权值,rudu是入度,t是存每一次入度为0的点,bo是判断是否作为入度为0点,chudu是出度
//mp是存每一次入度为0但是不能发出信号的点
int main()
{
int x,y,z;
scanf("%d %d",&n,&m);
int i,j,k;
for(j=1;j<=n;j++)
{
scanf("%d %d",&ms[j].c,&ms[j].u);
rudu[i]=0,chudu[i]=0;//归零
bo[i]=0;//归零
}//先存数据
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
tp[x][y]=z;//存边
rudu[y]++;//指向自己的+1
chudu[x]++;//自己指别人的+1
}
do{//得先做才能判断
top=0;//个数先归零
mop=0;
for(i=1;i<=n;i++)
{
if(rudu[i]==0&&ms[i].c-ms[i].u>0&&!bo[i])//入度为0是最下面一层,能发射信号,没被标记过
{
t[++top]=i;//先录入
bo[i]=1;//标记一下
}
else if(rudu[i]==0&&ms[i].c-ms[i].u<=0&&!bo[i])//入度为0但是不能发射信号
{
mp[++mop]=i;
bo[i]=1;
}
}
for(i=1,k=1;i<=top;i++)//去点去边
{
for(j=1;j<=n;j++)
{
if(tp[t[i]][j]!=0)//有边
{
ms[j].c+=tp[t[i]][j]*ms[t[i]].c;//公式
rudu[j]--;//去边
tp[t[i]][j]=0;
}
if(tp[mp[k]][j]!=0&&k<=mop)
{
tp[mp[k]][j]=0;
rudu[j]--;
}
}
k++;
}
}while(top);//直到都被标记或者只剩出度为0的最上层
for(i=1;i<=n;i++)
{
if(ms[i].c-ms[i].u>0&&chudu[i]==0)
{
num++;
printf("%d %d\n",i,ms[i].c-ms[i].u);
}
}
if(num==0)
printf("NULL");
return 0;
}
实在不知道这个代码错在哪··· 题目给的这个样例 5 6 1 0 1 0 0 1 0 1 0 1 1 3 1 1 4 1 1 5 1 2 3 1 2 4 1 2 5 1 是能过的