记录编号 177933 评测结果 AAAAAAAAAA
题目名称 [NOIP 2009]最优贸易 最终得分 100
用户昵称 Gravatar啊吧啦吧啦吧 是否通过 通过
代码语言 C++ 运行时间 0.429 s
提交时间 2015-08-12 21:17:30 内存使用 1.93 MiB
显示代码纯文本
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>

using namespace std;
typedef vector<int> vi;

const int MAXN(100001), MAXM(500001);
int n, m, a[MAXN], ans = 0, f[MAXN];
ifstream fin("trade.in");
ofstream fout("trade.out");
#define cin fin
#define cout fout
void dfs(int);
inline void spfa();
bool scc[MAXN] = {false}, que[MAXN] = {false};
queue<int> q;
vi g[MAXN];

main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 1; i <= n; ++i){
		cin >> a[i];	//a:自己价值(计算买入时用) 
		f[i] = a[i];	//f:能到的最大价值(计算卖出时用) 
	}
	for (int i = 1; i <= m; ++i){
		int x, y;
		short z;
		cin >> x >> y >> z;
		if (z == 1)
			g[y].push_back(x);	//反向存图 
		else{
			g[x].push_back(y);
			g[y].push_back(x);
		}
	}
	fin.close();
	
	dfs(n);	//所有能到n的点都搞到scc数组中,我感觉我好机智啊! 
	spfa();	//解释在下面的函数里 
	for (int i = 1; i <= n; ++i)
		ans = max(ans, f[i] - a[i]);
		
	cout << ans;
	fout.close();
}

void dfs(int root)
{
	if (scc[root])
		return;
	scc[root] = true;
	for (vi::iterator it = g[root].begin(); it != g[root].end(); ++it)
		dfs(*it);
}

inline void spfa(){
	for (int i = n; i > 0; --i){	//此处从终至始一个一个求f
		if(! scc[i])	//到不了终点的点滚一边去…… 
			continue;
		q.push(i);
//		que[i] = true;
		for (vi::iterator it = g[i].begin(); it != g[i].end(); ++it){
//			que[*it] = true;
			q.push(*it);
		}
		while (! q.empty()){
			int j = q.front();
			q.pop();
//			que[j] = false;
			for (vi::iterator it = g[j].begin(); it != g[j].end(); ++it){
				if (f[j] > f[*it]){	//如果j点的f值大于它前面点目前f值
					f[*it] = f[j]; 	//更新
					q.push(*it);	// 再以这个点为源点向前更新
//						que[*it] = true;
				}
			}
		} 
	}
}