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

差分约束系统

时间:2018-10-29 14:11:59      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:gif   info   tchar   ide   printf   alt   isp   closed   代码   

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<map>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
const int maxn=17000;
int lin[maxn],e[maxn],ver[maxn],nex[maxn],len=0;
int vis[maxn],flag=0,dis[maxn],q[maxn],h=0,t=1;;
void add(int x,int y,int z)
{
    ver[++len]=y;
    nex[len]=lin[x];
    lin[x]=len;
    e[len]=z;
}
int n,m;
int s1=1002,s2=1003,u[maxn];
void spfa(int x)
{
    memset(vis,0,sizeof(vis));
    memset(dis,-10,sizeof(dis));
    memset(q,0,sizeof(q));
    memset(u,0,sizeof(u));
    q[t]=x;dis[x]=0;vis[x]=1;
    while(h<=t)
    {
        int tn=q[++h];vis[tn]=0;
        for(int i=lin[tn];i;i=nex[i])
        {
            int tmp=ver[i];
            if(dis[tn]+e[i]>dis[tmp])
            {
                dis[tmp]=dis[tn]+e[i];
                if(vis[tmp]!=1)
                {
                    q[++t]=tmp;
                    vis[tmp]=1;
                    u[tmp]++;
                }
            }
            if(u[tmp]>=n+2){printf("NO\n");flag=1;return;}
        }
    }
}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();m=read();
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        x=read();y=read();z=read();
        if(z==1)add(x,y,1);
        if(z==-1)add(y,x,1);
        if(z==0)add(x,y,0),add(y,x,0);
    }
    for(int i=1;i<=n;i++)add(s1,i,0),add(i,s2,0);
    spfa(s1);if(flag==1)return 0;
    printf("%d\n",dis[s2]);
    return 0;
}
View Code

 

两天搞了一下差分约束,其实就是一堆不等式进而来求解。

1.建图并求解

2.x>y---> x>=y+1 表示从y到x连一条边 边权为1

3.x<y -----> y>x ------> y>=x+1 表示从x到y连一条边 边权为1

技术分享图片

输出 2

代码:

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<map>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
const int maxn=17000;
int lin[maxn],e[maxn],ver[maxn],nex[maxn],len=0;
int vis[maxn],flag=0,dis[maxn],q[maxn],h=0,t=1;;
void add(int x,int y,int z)
{
    ver[++len]=y;
    nex[len]=lin[x];
    lin[x]=len;
    e[len]=z;
}
int n,m;
int s1=1002,s2=1003,u[maxn];
void spfa(int x)
{
    memset(vis,0,sizeof(vis));
    memset(dis,-10,sizeof(dis));
    memset(q,0,sizeof(q));
    memset(u,0,sizeof(u));
    q[t]=x;dis[x]=0;vis[x]=1;
    while(h<=t)
    {
        int tn=q[++h];vis[tn]=0;
        for(int i=lin[tn];i;i=nex[i])
        {
            int tmp=ver[i];
            if(dis[tn]+e[i]>dis[tmp])
            {
                dis[tmp]=dis[tn]+e[i];
                if(vis[tmp]!=1)
                {
                    q[++t]=tmp;
                    vis[tmp]=1;
                    u[tmp]++;
                }
            }
            if(u[tmp]>=n+2){printf("NO\n");flag=1;return;}
        }
    }
}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();m=read();
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        x=read();y=read();z=read();
        if(z==1)add(x,y,1);
        if(z==-1)add(y,x,1);
        if(z==0)add(x,y,0),add(y,x,0);
    }
    for(int i=1;i<=n;i++)add(s1,i,0),add(i,s2,0);
    spfa(s1);if(flag==1)return 0;
    printf("%d\n",dis[s2]);
    return 0;
}
View Code

人家不是要你死才救你的,让人家救一回,又跑去死,是懦夫才会做的。 ——海贼王

差分约束系统

标签:gif   info   tchar   ide   printf   alt   isp   closed   代码   

原文地址:https://www.cnblogs.com/chdy/p/9870089.html

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