1.c<=0的点赋0,不然会影响后面的入度

2.最后输出层是出度为0的,且题干要求输出c大于0的

3.有q=0的情况,所以输的事后就会有答案

https://www.luogu.com.cn/problem/P1038

#include<bits/stdc++.h>
#include<string>
using namespace std;
#define N 100011
typedef long long ll;
typedef pair<int,int> pii;
int n;
ll p; 
int c[501];
int u[501];
int in[501];
typedef struct edge
{
	int v;ll w;
}edge;
vector<edge> mp[501];
queue<int> q;
set<int> a;
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
{
	cin>>c[i]>>u[i];
	if(!p&&c[i]>0) a.insert(i);///逆天点---1 0 2 10?qwq 
}
for(ll i=1;i<=p;i++)
{
	int x,y,w;
	cin>>x>>y>>w;
	in[y]++;
	mp[x].push_back({y,w}); 
}
for(int i=1;i<=n;i++)
{
	if(!in[i]&&c[i]>0)
	{
		q.push(i);
	}
}
while(q.size())///典型的拓扑排序 
{
	int t=q.front();
	q.pop();
	for(int i=0;i<mp[t].size();i++)
	{
	
		int v=mp[t][i].v;
		in[v]--;
		c[v]+=mp[t][i].w*c[t];
		if(in[v]<=0)
		{
			if(c[v]-u[v]>0)c[v]-=u[v];
			else c[v]=0;///重点,平静的c赋0,不能不考虑 
			q.push(v);
			if(!mp[v].size()&&c[v]>0)a.insert(v);///答案就是没有出度的且c>0的 
		}
	}
}
if(a.size())
{
set<int>::iterator it;
for(it=a.begin();it!=a.end();it++)
{
	cout<<*it<<" "<<c[*it]<<endl;
}	
}
else cout<<"NULL";
return 0;
}

Logo

集算法之大成!助力oier实现梦想!

更多推荐