题解 UVA1723 【Intervals】
发布于 2020-11-21
题意
有n个如下形式的条件:
ai bi ci,表示在区间[ai, bi]内至少要选择ci个整数点。
问你满足n个条件的情况下,最少需要选多少个点?
题解
就差分约束呗......
何为差分约束:如果一个系统由n个变量和m个约束条件组成,形成m个形如ai-aj≤k的不等式(i,j∈[1,n],k为常数),则称其为差分约束系统。
由此,可以把它转化为图,跑一波SPFA就完事了。
代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<iostream>
using namespace std;
struct node
{
int u,v,w;
int next;
}wee[500001];
int minnnn=0x7f,maxxxx=-1;//最小和最大
int n,h[500001],cnt;
int u,v,w;
int vis[500001],stackto[500001],qwq[500001];
void add(int u,int v,int w)
{
wee[++cnt].u=u;
wee[cnt].v=v;
wee[cnt].w=w;
wee[cnt].next=h[u];
h[u]=cnt;
}
bool spfa()
{
stack<int>st;
while(!st.empty()) st.pop();
memset(stackto,0,sizeof(stackto));
memset(qwq,0,sizeof(qwq));
for(int i=minnnn;i<=maxxxx;i++)
vis[i]=-0x7f;
st.push(minnnn);
vis[minnnn]=0;
stackto[minnnn]=1;
qwq[minnnn]++;
while(!st.empty())
{
int u=st.top();
st.pop();
stackto[u]=0;
for(int i=h[u];i!=0;i=wee[i].next)
{
if(vis[wee[i].v]<vis[u]+wee[i].w)
{
vis[wee[i].v]=vis[u]+wee[i].w;
if(!stackto[wee[i].v])
{
stackto[wee[i].v]=1;
st.push(wee[i].v);
qwq[wee[i].v]++;
if(qwq[wee[i].v]>n)
return false;
}
}
}
}
return true;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>u>>v>>w;
add(u,v+1,w);
minnnn=min(minnnn,u);
maxxxx=max(maxxxx,v+1);
}
for(int i=minnnn;i<maxxxx;i++)
{
add(i,i+1,0);
add(i+1,i,-1);
}
spfa();//万能的spfa
cout<<vis[maxxxx]-vis[minnnn]<<endl;
return 0;
}