【NOIP模拟 180731 T3】食堂 (差分约束)
Problem:
在SD食堂,所有的座位是一行一行的排列。现在有N个座位排成一行,依次编号1,2,…,N,每个座位只能坐一个人,现在L想数一下有多少个人坐着,一个一个数太慢了,L决定只选择M段连续的座位,对每段分别数出人数。由于食堂噪音十分嘈杂,L无法专心,可能有输错了。但是L认为没有数漏,最多是重复计数导致的。现在他把得到的数据给你,希望你帮他算出,一共最多有多少人。(n,m<=100000)
输入
第一行2个整数N,M,分别是座位数量,和L分成M段
接下来M行,每行3个整数,l,r,k,表示L数了l到r这一段的座位,他数出的结构是k
输出
一行表示答案
Solution:
考虑差分约束
明确所求:最大值;因此跑最短路,把所有不等式的符号变为<=,从小的向大的连边。
当然,差分约束不能忘了要分析两两元素之间隐晦的关系,比如这道题,我们会发现1>=sum[i]-sum[i-1]>=0,需要预连边。
Code
#include<bits/stdc++.h>
#define N 200005
using namespace std;
int n,m,sum[N],tot,first[N],zdl[N];
bool inque[N];
struct node
{
int to,next,val;
}edge[2*N];
inline void addedge(int x,int y,int z)
{
tot++;
edge[tot].to=y;
edge[tot].next=first[x];
edge[tot].val=z;
first[x]=tot;
}
inline void spfa(int s)
{
queue <int> q;
q.push(s);
inque[s]=true;
zdl[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
inque[now]=false;
for(int u=first[now];u;u=edge[u].next)
{
int vis=edge[u].to;
if(zdl[now]+edge[u].val<zdl[vis])
{
zdl[vis]=zdl[now]+edge[u].val;
if(!inque[vis])
{
inque[vis]=true;
q.push(vis);
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
memset(zdl,127,sizeof(zdl));
cin>>n>>m;
for(int i=1;i<=n;i++)
{
addedge(i,i-1,0);
addedge(i-1,i,1);
}
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
addedge(x-1,y,z);
}
spfa(0);
cout<<zdl[n];
return 0;
}
QQ40523591~欢迎一起学习交流~

浙公网安备 33010602011771号