noip2009

最优贸易

。。。看错题了。如果题意理解正确的话还是比较好想的spfa或dij处理i之前和之后的最大最小值,但这多少有点感性。更清楚的是一篇题解里介绍的分层图+spfa的方法。

code

#include<bits/stdc++.h>
#define fi first
#define se second
#define MP make_pair
#define Pit pair<int,int>
using namespace std;
const int N=1e5+5,oo=0x3f3f3f3f;

vector<Pit > G[N*3];
queue<int> Q;
int a[N],in[N*3],dis[N*3];
int n,m; 

void add(int x,int y)
{
	G[x].push_back(MP(y,0));
	G[x+n].push_back(MP(y+n,0));
	G[x+n+n].push_back(MP(y+n+n,0));
	G[x].push_back(MP(y+n,-a[x]));
	G[x+n].push_back(MP(y+n+n,a[x]));
}

void spfa()
{
	for(int i=1;i<=n;i++) dis[i]=-oo;
	Q.push(1); in[1]=1; dis[1]=0;
	
	while(Q.size())
	{
		int x=Q.front(); Q.pop();
		in[x]=0;
		for(auto i:G[x])
			if(dis[x]+i.se>dis[i.fi])
			{
				dis[i.fi]=dis[x]+i.se;
				if(!in[i.fi]) { Q.push(i.fi); in[i.fi]=1; }
			}
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	for(int i=1;i<=m;i++)
	{
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		add(x,y);
		if(z==2) add(y,x);
	}
	G[n].push_back(MP(3*n+1,0));
	G[n*3].push_back(MP(3*n+1,0));
	n=3*n+1;
	
	spfa();
	
	cout<<dis[n]<<endl;
	return 0;
}

posted @ 2019-08-27 15:24  小蒟蒻lzq  阅读(137)  评论(0编辑  收藏  举报