Loading...

洛谷P4878 [USACO05DEC]layout布局

check评论:0 条 remove_red_eye浏览量:471 change_historyTags:编程学习笔记
作者 : deco date_range日期 : 2018-09-22

差分约束裸题,有人恶意评分导致它黑了

这个题唯一需要注意的就是如果图不连通,从$1$开始$spfa$可能不会遍历所有点,就不会发现一些负环,我们需要从$0$往所有点都连一条边,$0$和$1$各跑一次$spfa$

然后就是标准的差分约束$+$找负环了

#include <bits/stdc++.h>
using namespace std;
struct edge
{
    int next,to,dis;
    edge(int n,int t,int d):next(n),to(t),dis(d){}
    edge(){}
}e[200020];
int n,m1,m2,vis[100010],dis[100010],cnt[100010],tot,head[100010],flag;
void add(int u,int v,int dis)
{
    tot++;
    e[tot]=edge(head[u],v,dis);
    head[u]=tot;
}
void spfa(int x=1)
{
    queue<int> q;
    memset(dis,0x3f,sizeof(dis));
    q.push(x);
    dis[x]=0;
    vis[x]=1;
    cnt[x]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].next)
        {
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].dis)
            {
                dis[v]=dis[u]+e[i].dis;
                cnt[v]=cnt[u]+1;
                if(cnt[v]>n)
                {
                    cout<<"-1";
                    flag=1;
                    return ;
                }
                if(!vis[v])
                {
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}
int main()
{
    cin>>n>>m1>>m2;
    for(int i=1;i<=n;i++)
    {
        add(0,i,0);
    }
    for(int i=1;i<=m1;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
    }
    for(int i=1;i<=m2;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(y,x,-z);
    }
    spfa(0);
    spfa();
    if(flag)
    {
        return 0;
    }
    if(dis[n]==0x3f3f3f3f)
    {
        cout<<"-2";
        return 0;
    }
    cout<<dis[n];
}

暂无评论

正在回复给  
去登陆?

   点击刷新验证码

标签云

文章留名