BZOJ2330(SCOI2011)[糖果]--差分约束系统

【链接】
bzoj2330

【解题报告】

差分约束系统裸题。不会可以去看百科。

Ps:注意加一个点会T。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int maxn=100005,maxm=300005;
int n,m,tot,dst[maxn],num[maxn],que[maxn],lnk[maxn],son[maxm],nxt[maxm];
bool vis[maxn],w[maxm];
LL ans;
inline char nc()
{
    static char buf[100000],*l,*r;
    if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
    if (l==r) return EOF; return *l++;
}
inline int Read()
{
    int res=0; char ch=nc();
    while (ch<'0'||ch>'9') ch=nc();
    while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=nc();
    return res;
}
void Add(int x,int y,bool z) {w[++tot]=z; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot;}
bool Spfa()
{
    memset(num,0,sizeof(num));
    int hed=0,til=0;
    for (int i=1; i<=n; i++) que[til=(til+1)%maxn]=i,vis[i]=1,dst[i]=1;
    while (hed!=til)
    {
        int x=que[hed=(hed+1)%maxn]; vis[x]=0;
        for (int j=lnk[x]; j; j=nxt[j])
         if (dst[x]+w[j]>dst[son[j]])
          {
            if (++num[son[j]]>=n) return 0;
            dst[son[j]]=dst[x]+w[j];
            if (!vis[son[j]])
             {
                que[til=(til+1)%maxn]=son[j]; vis[son[j]]=1;
                if (dst[que[til]]>dst[que[(hed+1)%maxn]]) swap(que[til],que[(hed+1)%maxn]);
             }
          }
    }
    return 1;
}
int main()
{
    freopen("2330.in","r",stdin);
    freopen("2330.out","w",stdout);
    n=Read(); m=Read(); tot=0;
    memset(lnk,0,sizeof(lnk));
    for (int i=1; i<=m; i++)
    {
        int x=Read(),a=Read(),b=Read();
        switch (x)
        {
            case 1:Add(a,b,0);Add(b,a,0);break;
            case 2:if (a==b) {printf("-1"); return 0;}
                   Add(a,b,1);break;
            case 3:Add(b,a,0);break;
            case 4:if (a==b) {printf("-1"); return 0;}
                   Add(b,a,1);break;
            case 5:Add(a,b,0);break;
        }
    }
    if (!Spfa()) {printf("-1"); return 0;}
    ans=0; for (int i=1; i<=n; i++) ans+=dst[i];
    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值