[BZOJ3436]小K的农场(差分约束)
来源:互联网 发布:单片机论坛网430 编辑:程序博客网 时间:2024/05/18 03:07
题目描述
传送门
题目大意:n个点每一个点有一个权,有m个限制:1 a b c
d(a)-d(b)>=c; 2 a b c
d(a)-d(b)<=c;3 a b
d(a)=d(b),判断是否有可行解
题解
对于三个限制移项啥的可以化出来一些不等式:d(b)<=d(a)-c;d(a)<=d(b)+c;d(b)<=d(a),d(a)<=d(b)
对于一个形如d(x)<=d(y)+z的等式,连边y->x,z构造出最短路模型
这道题没有源点,所以强行加一个源点0,然后因为要从源点连向每一个点,所以强行d(i)<=d(0)
设d(0)=0,虽然求出来的所有的d都是非正数,但是所有的d同时加上一个数都是可行解,所以没有影响;只需要看图中是否有负权环即可
用深搜版spfa判断负环快很多很多…
代码
普通spfa
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<queue>using namespace std;#define N 10005#define E 50005int n,m,ans;int tot,point[N],nxt[E],v[E],c[E];int dis[N],cnt[N];bool vis[N];queue <int> q;void add(int x,int y,int z){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;}int spfa(){ memset(dis,127,sizeof(dis)); dis[0]=0;vis[0]=1;cnt[0]=1;q.push(0); while (!q.empty()) { int now=q.front();q.pop(); vis[now]=0; for (int i=point[now];i;i=nxt[i]) if (dis[v[i]]>dis[now]+c[i]) { dis[v[i]]=dis[now]+c[i]; if (!vis[v[i]]) { ++cnt[v[i]]; if (cnt[v[i]]>n) return 0; vis[v[i]]=1; q.push(v[i]); } } } return 1;}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;++i) { int opt,a,b,c;scanf("%d",&opt); if (opt==1) { scanf("%d%d%d",&a,&b,&c); add(a,b,-c); } else if (opt==2) { scanf("%d%d%d",&a,&b,&c); add(b,a,c); } else { scanf("%d%d",&a,&b); add(a,b,0);add(b,a,0); } } for (int i=1;i<=n;++i) add(0,i,0); ans=spfa(); if (!ans) puts("No"); else puts("Yes");}
深搜版spfa
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<queue>using namespace std;#define N 10005#define E 50005int n,m;int tot,point[N],nxt[E],v[E],c[E];int dis[N];bool vis[N],flag;queue <int> q;void add(int x,int y,int z){ ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=z;}void spfa(int x){ vis[x]=1; for (int i=point[x];i;i=nxt[i]) if (dis[v[i]]>dis[x]+c[i]) { dis[v[i]]=dis[x]+c[i]; if (vis[v[i]]) { flag=1; return; } spfa(v[i]); if (flag) return; } vis[x]=0;}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;++i) { int opt,a,b,c;scanf("%d",&opt); if (opt==1) { scanf("%d%d%d",&a,&b,&c); add(a,b,-c); } else if (opt==2) { scanf("%d%d%d",&a,&b,&c); add(b,a,c); } else { scanf("%d%d",&a,&b); add(a,b,0);add(b,a,0); } } for (int i=1;i<=n;++i) add(0,i,0); memset(dis,127,sizeof(dis));dis[0]=0; flag=0;spfa(0); if (!flag) puts("Yes"); else puts("No");}
0 0
- [BZOJ3436]小K的农场(差分约束)
- 【BZOJ3436】小K的农场(差分约束)
- 【bzoj3436】 小K的农场 差分约束系统
- bzoj3436 小K的农场 差分约束系统
- [bzoj3436][差分约束]小K的农场
- 小K的农场 差分约束
- ssoj1750小K 的农场(差分约束系统)
- BZOJ 3436 小k的农场(差分约束)
- bzoj 3436: 小K的农场 (差分约束)
- 【luogu1993】小 K 的农场(差分约束)
- 小K的农场(差分约束)
- 洛谷P1993 小K的农场(差分约束)
- BZOJ3436:小K的农场
- bzoj3436 小K的农场
- 【bzoj】3436 小k的农场 差分约束
- 小K的农场 洛谷1993 差分约束
- 差分约束——Luogu1993 小K的农场
- BZOJ 3436: 小K的农场 差分约束
- (转) 关于C++面试中一点小问题
- url 验证
- TextView使用技术点(一)
- Vue从入门到精通(2)--第一阶段
- VirtualProtect,是对应 Win32 函数的逻辑包装函数,它会在呼叫处理程序的虚拟位址空间里,变更认可页面区域上的保护。
- [BZOJ3436]小K的农场(差分约束)
- DELETE_FAILED_INTERNAL_ERROR Error while Installing APK
- java中Iterator迭代器
- [51nod1238]最小公倍数之和
- 我们总是喜欢拿顺其自然来敷衍人生道路上的荆棘坎坷,却很少承认,真正的顺其自然是竭尽所能之后的不强求,而非两手一摊的不作为。
- JAVA与C#的区别
- InnoDB基础
- mysql数据库
- 关于Android Studio 报Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger fa