P1250 種樹 差分約束

跟上一題一樣:轉化爲sm[i],表示前i個區域種多少課樹。

建立不等式跑最短路即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;

int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}

int d[M],vs[M];
int n,m,N;
void spfa()
{
	memset(d,0x3f,sizeof(d));
	queue<int>q;
	q.push(50001);
	d[50001]=0;vs[50001]=1;
	while(q.size())
	{
		int x=q.front();q.pop();
		vs[x]=0;
		for(int i=head[x];i;i=ee[i].nxt)
		{
			int y=ee[i].to,w=ee[i].w;
	//		cout<<x<<" "<<y<<"  "<<w<<"  "<<d[x]<<"  "<<d[y]<<endl;
			if(d[y]>d[x]+w)
			{
				d[y]=d[x]+w;
				if(!vs[y])q.push(y),vs[y]=1;
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cin>>N>>n;
  	for(int i=1;i<=n;i++)
  	{
  		int x,y,w;
  		cin>>x>>y>>w;
  		y++;
  		//y-x>=c    x<=-c+y
  		add(y,x,-w);
	}
	// d[i]-d[i-1]>=0  -> d[i-1]<=d[i]+0
	// d[i]-d[i-1]<=1  -> d[i]<=d[i-1]+1
	// d[ed]-d[0]>=0    -> d[0]<=d[ed]  求出 d[0]-d[ed] 即 -d[ed] 的最大值 
	for(int i=1;i<=50001;i++)add(i,0,0),add(i-1,i,1),add(i,i-1,0);//超級原點,目的是求每個點的最小值 
	spfa();//一定有解 ,即不存在負環 	
	cout<<-d[0]<<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章