BZOJ 2330 [SCOI2011]糖果 ——差分约束系统 SPFA
2024-08-31 08:32:13
最小值求最长路。
最大值求最短路。
发现每个约束条件可以转化为一条边,表示一个点到另外一个点至少要加上一个定值。
限定了每一个值得取值下界,然后最长路求出答案即可。
差分约束系统,感觉上更像是两个变量之间约束的线性规划问题。
想了想怎么可能有-1的情况,原来2、4操作中a、b相同的时候会造成一个环
#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
#define maxn 800005 int n,k,flag=0;
int h[maxn],to[maxn],ne[maxn],en=0,w[maxn],inq[maxn],tim[maxn];
queue <int> q;
ll dis[maxn],ans; void add(int a,int b,int c)
{
to[en]=b;ne[en]=h[a];w[en]=c;h[a]=en++;
} void SPFA()
{
memset(dis,-1,sizeof dis);
dis[0]=0;inq[0]=1;q.push(0);tim[0]++;
while (!q.empty())
{
int x=q.front(); q.pop(); inq[x]=0;
for (int i=h[x];i>=0;i=ne[i])
if (dis[to[i]]<dis[x]+w[i]){
dis[to[i]]=dis[x]+w[i];
if (!inq[to[i]])
{
inq[to[i]]=1;
tim[to[i]]++;
if (tim[to[i]]>n)
{
printf("-1\n");
return ;
}
q.push(to[i]);
}
}
}
F(i,1,n) ans+=dis[i];
printf("%lld\n",ans);
} int main()
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&k);
F(i,1,k)
{
int x,a,b;scanf("%d%d%d",&x,&a,&b);
switch(x)
{
case 1: add(a,b,0);add(b,a,0);break;
case 2: add(a,b,1); if (a==b) flag=1; break;
case 3: add(b,a,0);break;
case 4: add(b,a,1); if (a==b) flag=1; break;
case 5: add(a,b,0);break;
}
}
D(i,n,1) add(0,i,1);
if (flag) {printf("-1\n");return 0;}
SPFA();
}
最新文章
- ASP.NET Core 中文文档 第三章 原理(7)配置
- 考前预习(Ubuntu配备)
- [Asp.net MVC]Asp.net MVC5系列——添加视图
- Oracle RAC OCR 的管理与维护
- C#编写以管理员身份运行的程序
- (十一)学习CSS之float属性
- C#字符串拼接怎么转义背景图片
- Android新浪微博客户端(三)——添加多个账户及认证
- hadoop默认3个核心配置文件说明
- HDOJ 1598 Kruscal
- 关于QT中的音频通信问题
- visio流程图软件
- CentOS6.8虚拟机安装及ORALCE安装记录
- RSA加密传输代码示例
- mysql 连接超慢
- linux 服务器时间同步
- mysql 开发基础系列13 选择合适的数据类型(下)
- flask 单个表单多个提交按钮
- TCP/IP学习20180624
- WCF的简单使用