您的位置:首页 > 其它

bzoj2330 糖果 差分约束

2015-11-28 22:35 344 查看
简单的差分约束系统。a-b>=c转化为b->a连一条长度为c的边,跑最长路,这样可以保证满足不等号。a=b转化为a>=b且b>=a即可。spfa判正权回路即可。

P·S:一个m打成n查了半天。。汗(⊙﹏⊙)b。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define N 400005
using namespace std;

int n,m,tot,fst
,pnt
,len
,nxt
,d
,h
,sum
;
bool bo
;
int read(){
int x=0; char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
return x;
}
void add(int aa,int bb,int cc){
pnt[++tot]=bb; len[tot]=cc; nxt[tot]=fst[aa]; fst[aa]=tot;
}
bool spfa(){
int head=0,tail=n,i;
for (i=1; i<=n; i++){ h[i]=i; d[i]=sum[i]=1; }
while (head!=tail){
head=(head+1)%N;
int x=h[head],p; bo[x]=1;
for (p=fst[x]; p; p=nxt[p]){
int y=pnt[p];
if (d[x]+len[p]>d[y]){
d[y]=d[x]+len[p];
sum[y]++; if (sum[y]>n) return 0;
if (bo[y]){
bo[y]=0; tail=(tail+1)%N;
h[tail]=y;
}
}
}
}
return 1;
}
int main(){
n=read(); m=read(); int i;
for (i=1; i<=m; i++){
int k=read(),x=read(),y=read();
if (k==1){ add(x,y,0); add(y,x,0); } else
if (k==2){ if (x==y){ puts("-1"); return 0; } add(x,y,1); } else
if (k==4){ if (x==y){ puts("-1"); return 0; } add(y,x,1); } else
if (k==3) add(y,x,0); else add(x,y,0);
}
if (!spfa()) puts("-1"); else{
ll ans=0; for (i=1; i<=n; i++) ans+=(ll)d[i];
printf("%lld\n",ans);
}
return 0;
}<em>
</em>


2015.11.28

by lych
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: