bzoj2330: [SCOI2011]糖果

差分约束,dag最长路。

坑点在于有一个100000 长的链,虚拟节点倒序加就a了。

用queue是太懒,tyvj上过不了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 100000 + 10;
const int maxm = 400000 + 10;

int n,k;
int g[maxn],v[maxm],next[maxm],d[maxm],eid=0;
queue<int> q;
bool inque[maxn];
int t[maxn],f[maxn];

void addedge(int a,int b,int D) {
    v[eid]=b; d[eid]=D; next[eid]=g[a]; g[a]=eid++;
}

void build() {
    scanf("%d%d",&n,&k);
    memset(g,-1,sizeof(g));
    for(int i=1,u,v,x;i<=k;i++) {
        scanf("%d%d%d",&x,&u,&v);
    switch(x) {
        case 1:
            addedge(u,v,0);
            addedge(v,u,0);
        break;
        
        case 4:
            swap(u,v);
        case 2:
            addedge(u,v,1);
        break;
        
        case 3:
            swap(u,v);
        case 5:
            addedge(u,v,0);
        break; 
    }
    }
    for(int i=n;i>=1;i--) addedge(0,i,1);
    //printf("sda");
}

long long SPFA() {
    memset(f,0xef,sizeof(f));
    q.push(0); f[0]=0; inque[0]=1;
    while(!q.empty()) {
        int u = q.front(); q.pop();
        inque[u]=0;
        for(int i=g[u];~i;i=next[i]) 
        if(f[v[i]] < d[i]+f[u]) {
            f[v[i]] = d[i]+f[u];
            t[v[i]] = t[u]+1;
            if(t[v[i]]>=n+1) 
                return -1;
            if(!inque[v[i]]) q.push(v[i]),inque[v[i]]=1;
        }
    }
    long long res=0;
    for(int i=1;i<=n;i++) 
        res+=f[i];
    return res;
}

void solve() {
    printf("%lld\n",SPFA());
}

int main() {
    build();
    solve();
    
    return 0;
}

posted @ 2016-04-25 22:21  invoid  阅读(134)  评论(0编辑  收藏  举报