[NOIp复习计划]:差分约束

13 篇文章 0 订阅

[bzoj 2300][SCOI2011]糖果
做了这题长了教训,千万别用vector存图,千万别想偷懒!!!
这里写图片描述
剩下的没什么啦。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,ll> S;
typedef vector<S> P;
const int maxn = 100005; 
vector<P> mp;
ll read(){
    ll rt=0,fl=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')fl=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){rt=rt*10+ch-'0';ch=getchar();}
    return rt*fl;
}
ll n,k;
ll d[maxn];
int cnt[maxn],h[maxn],nx[maxn<<2],to[maxn<<2];
ll v[maxn<<2],tot;
bool vis[maxn],inq[maxn];
int q[maxn*5],l,r;
void insert(int a,int b,int c){
    //mp[a].push_back(S(b,c));
    to[++tot]=b;v[tot]=c;
    nx[tot]=h[a];h[a]=tot;
}
int spfa(){
    //q.push(0);
    q[r++]=0;
    cnt[0]=inq[0]=1;
    while(l!=r){
        int t=q[l++];if(l==maxn)l=0;
        for(int i=h[t];i;i=nx[i]){
            int now=to[i];
            if(d[now] < d[t] + v[i]){
                d[now] = d[t] + v[i];
                cnt[now]++;
                if(cnt[now] > n + 1){
                    return 0;
                }
                if(inq[now]==0){
                    //q.push(now.first);
                    q[r++]=now;
                    if(r==maxn)r=0;
                    inq[now]=1;
                }
            }
        }
        inq[t]=0;
    }
    return 1;
}
ll ans=0;
int main(){
    n=read();k=read();
    ll x,a,b;
    while(k--)
    {
       x=read();a=read();b=read();
       switch(x)
       {
                case 1:insert(a,b,0);insert(b,a,0);break;
                case 2:if(a==b){printf("-1");return 0;}
                     insert(a,b,1);break;
                case 3:insert(b,a,0);break;
                case 4:if(a==b){printf("-1");return 0;}
                     insert(b,a,1);break;
                case 5:insert(a,b,0);break;
                }
       }
    for(int i=n;i>0;i--)insert(0,i,1);
    if(!spfa()){printf("-1");return 0;}
    for(int i=1;i<=n;i++)ans+=d[i];
    printf("%lld",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值