【刷题】【差分约束】布局

两组hack数据真的很hack

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;
int max(int a,int b)
{ return a>b ?a :b; }
int n,m1,m2;
const int N=1003,M=3e4+3;

int tot,head[N];
int ev[M],ew[M],enx[M];
void add(int u,int v,int w)
{ ev[++tot]=v,ew[tot]=w,enx[tot]=head[u],head[u]=tot; }

int dis[N],tm[N];
bool in[N];
void SPFA(int st)
{
    memset(dis,0x3f,sizeof(dis));
    memset(tm,0,sizeof(tm));
    queue <int> q;
    q.push(st),dis[st]=0;
    
    while(!q.empty() )
    {
        int t=q.front() ;q.pop() ;
        for(int i=head[t];i;i=enx[i])
        {
            int v=ev[i];
            
            if(dis[v]>dis[t]+ew[i])
            {
                dis[v]=dis[t]+ew[i];
                if(++tm[v]>=n)
                {
                    dis[n]=-1;//但是,由于不合法的优先级在前 
                    return;//如果有正环但是,不与1相连,就错了  
                }
                if(!in[v])
                    in[v]=true,q.push(v); 
            }
        }
        in[t]=false;
    }
    if(dis[n]==dis[n+1]) dis[n]=-2;
}

int main()
{
    scanf("%d%d%d",&n,&m1,&m2);
    int u,v,w;
    for(int i=1;i<=m1;i++)
        scanf("%d%d%d",&u,&v,&w),add(u,v,w);
    for(int i=1;i<=m2;i++)
        scanf("%d%d%d",&u,&v,&w),add(v,u,-w);
    for(int i=2;i<=n;i++)
        add(i,i-1,0);
    
    //bug解决方案,跑两遍spfa,一遍从0出发!!! 
    for(int i=1;i<=n;i++)
        add(0,i,0);
    SPFA(0);
    if(dis[n]==-1)
    {
        printf("-1\n");
        return 0;
    }
    SPFA(1);
    printf("%d\n",dis[n]);
    
    return 0;
} 

 

posted @ 2019-10-21 19:25  心若笺诗  阅读(101)  评论(0编辑  收藏  举报