码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2330糖果

时间:2018-04-19 00:31:40      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:print   cst   int   http   scan   --   set   main   tar   

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2330

差分约束裸题。练习用spfa判正环(一个点入队超过n次)。

据说有1e5个点连成一条链的数据,使得0点从1到n加边会TLE,而从n到1加边就300ms。为什么?

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e5+5;
int n,m,head[N],xnt,dis[N],ct[N];
long long ans;
bool in[N];
struct Edge{
    int next,to,w;
    Edge(int n=0,int t=0,int w=0):next(n),to(t),w(w) {}
}edge[N*3];
bool spfa()
{
    queue<int> q;
    memset(dis,-1,sizeof dis);
    q.push(0);in[0]=1;dis[0]=0;
    while(q.size())
    {
        int k=q.front();q.pop();in[k]=0;
        for(int i=head[k],v;i;i=edge[i].next)
            if(dis[k]+edge[i].w>dis[v=edge[i].to])
            {
                if(++ct[v]>=n)return 1;
                dis[v]=dis[k]+edge[i].w;
                if(!in[v])q.push(v),in[v]=1;
            }
    }
    return 0;
}
int main()
{
    scanf("%d%d",&n,&m);int k,x,y;
    for(int i=n;i;i--)//
        edge[++xnt]=Edge(head[0],i,1),head[0]=xnt;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&k,&x,&y);
        if(k==1)
        {edge[++xnt]=Edge(head[x],y,0);head[x]=xnt;
            edge[++xnt]=Edge(head[y],x,0);head[y]=xnt;}
        if(k==2){if(x==y){printf("-1");return 0;}
                    edge[++xnt]=Edge(head[x],y,1),head[x]=xnt;}
        if(k==3)edge[++xnt]=Edge(head[y],x,0),head[y]=xnt;
        if(k==4){if(x==y){printf("-1");return 0;}
                    edge[++xnt]=Edge(head[y],x,1),head[y]=xnt;}
        if(k==5)edge[++xnt]=Edge(head[x],y,0),head[x]=xnt;
    }
    if(spfa())
    {
        printf("-1");return 0;
    }
    for(int i=1;i<=n;i++)ans+=dis[i];
    printf("%lld",ans);
    return 0;
}

 

bzoj2330糖果

标签:print   cst   int   http   scan   --   set   main   tar   

原文地址:https://www.cnblogs.com/Narh/p/8878589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!