P3084 [USACO13OPEN]照片(差分约束)

 (已经有了简化版题面)

又秒了一次dp233

本来按照感觉瞎写了一发...

但还是老老实实列式子吧....

对差分约束有了更深的理解

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
/*
不等式*3
设前i头奶牛有斑点牛d[]个,设lr为给定区间
则:
1、每个区间有且只有一头奶牛有斑点=>d[r]-d[l-1]=1; 
2、两只相邻的奶牛要么有斑点要么没斑点=>0<=d[i]-d[i-1]<=1;
改写方程得:

d[r]-d[l-1]<=1
d[l-1]-d[r]<=-1
d[i]-d[i-1]<=1
d[i-1]-d[i]<=0

于是:

l-1->r 1
r->l-1 -1
i-1->i 1
i->i-1 0

然后流氓优化+负环spfa卡过了这道题
*/ 
const int maxn=1e6+10;
int n,m;
inline int read()
{
    int x=0,f=1;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    return x*f;
}
struct edge
{
    int to,next,dis;
}e[maxn];
int head[maxn],cnt;
inline void addedge(int from,int to,int dis)
{
    e[++cnt].next=head[from];
    e[cnt].to=to;
    e[cnt].dis=dis;
    head[from]=cnt;
}
int dis[maxn],vis[maxn];
struct cmp
{
    bool operator()(int a,int b)
    {
        return dis[a]>dis[b];
    }
};
//queue < int > q;
int tot=0;
priority_queue < int , vector < int > , cmp > q;
inline void spfa(int s)
{
    /*for(int i=1;i<=n;i++)
    {
        dis[i]=2147483647;
    }*/
    memset(dis,0x7f,sizeof(dis));
    q.push(s);
    vis[s]=1;
    dis[s]=0;
    while(!q.empty())
    {
        int u=q.top();
        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;
                if(vis[v]==0)
                {
                    if(++tot>1000000)
                    {
                        printf("-1");
                        exit(0);
                    }
                    q.push(v);
                    vis[v]=1;
                }
            }
        }
    }
}


int main()
{
    n=read();m=read();//scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        x=read();y=read();//scanf("%d%d",&x,&y);
        addedge(x-1,y,1);
        addedge(y,x-1,-1);
    }
    for(int i=1;i<=n;i++)
    {
        addedge(i,i-1,0);
        addedge(i-1,i,1);
    }
    spfa(0);
    printf("%d",dis[n]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ajmddzp/p/11643830.html
今日推荐