差分约束模板题

http://poj.org/problem?id=1201

题意是给你n个区间,每个区间有一个边界[a,b],以及一个整数c

要满足每个区间[a,b]都至少有c个元素

解题方法就是构造差分约束公式

(a-1)-b<=-c

建立一条边从b到a-1,权值为-c

然后还要加上两个条件

(i+1)-i>=0 -> i-(i+1)<=0

(i+1)-i<=1

建立i+1 到 i 权值为 0的边

建立i到i+1 权值为1的边

跑一边spfa就解决

#include <cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define N 50005
#define M 500009
const int inf=0x3f3f3f3f;
int dis[N],head[N];
queue<int> q;
int tot;
bool vis[N];
struct Edge
{
    int from,to,cost,next;
} edge[M];
void add(int u,int v,int w)
{
    edge[tot].from=u;
    edge[tot].to=v;
    edge[tot].cost=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void spfa(int u)
{
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[u]=0;
    q.push(u);
    vis[u]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for(int i=head[x]; ~i; i=edge[i].next)
        {
            int y=edge[i].to;
            if(dis[x]+edge[i].cost<dis[y])
            {
                dis[y]=dis[x]+edge[i].cost;
                if(!vis[y]) vis[y]=1,q.push(y);
            }
        }
    }
}
void init()
{
    memset(head,-1,sizeof(head));
    tot=0;
}
int main()
{

    int n;
    while(~scanf("%d",&n))
    {
        init();
        int a,b,w;
        int mina=1e9,maxb=-mina;
        for (int i=0; i<n ; i++ )
        {
            scanf("%d%d%d",&a,&b,&w);
            a++;
            b++;
            add(b,a-1,-w);
            mina=min(mina,a);
            maxb=max(maxb,b);
        }
        for (int i=mina-1; i<maxb ; i++ )
        {
            add(i+1,i,0);
            add(i,i+1,1);
        }
        int s=maxb;
        int t=mina-1;

        spfa(s);
        printf("%d",-dis[t]);
    }
    return 0;
}

 https://cn.vjudge.net/problem/POJ-2983

题意给点n个点m条有向边

如果输入P则改边长度确定,如果输入V则改边长度大于等于1

问是否满足所有的条件

将确定边的条件设为

1<=(u,v)<=1

不确定边的条件设为

(u,v)>=1 -> (v,u)<=-1

并且建立一个超级源点0指向所有点

跑一边spfa,出现负环则说明矛盾.

#include <cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define N 50005
#define M 500009
const int inf=0x3f3f3f3f;
int dis[N],head[N];
int fax[N];
int n,m;
queue<int> q;
int tot;
bool vis[N];
struct Edge
{
    int from,to,cost,next;
} edge[M];
void add(int u,int v,int w)
{
    edge[tot].from=u;
    edge[tot].to=v;
    edge[tot].cost=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
bool spfa(int u)
{
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[u]=0;
    q.push(u);
    vis[u]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for(int i=head[x]; ~i; i=edge[i].next)
        {
            int y=edge[i].to;
            if(dis[x]+edge[i].cost<dis[y])
            {
                dis[y]=dis[x]+edge[i].cost;
                if(!vis[y])
                {
                        fax[y]++;
                        vis[y]=1;
                        q.push(y);
                        if(fax[y]>n)
                                return false;
                }
            }
        }
    }
    return true;
}
void init()
{
    memset(head,-1,sizeof(head));
    memset(fax,0,sizeof(fax));
    tot=0;
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        getchar();
        init();
        for (int i=1;i<=n ;i++ )
            add(0,i,0);
        int a,b,w;
        for (int i=0; i<m ; i++ )
        {
            char ch=getchar();
            if(ch=='P')
            {
                scanf(" %d %d %d",&a,&b,&w);
                add(a,b,w);
                add(b,a,-w);
            }
            else
            {
                scanf(" %d %d",&a,&b);
                add(b,a,-1);
            }
            getchar();
        }
        if(spfa(0))
        {
                printf("Reliable
");
        }
        else
        {
                printf("Unreliable
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Json-Five/p/9783621.html