poj1364King

题目大意:

有一个序列S={a1 ,a2 ........an}, 现在告诉你许多区间从第i个元素到第i+n个元素的和的范围是大于K或者小于K,问你这些条件是否能够同时满足。

解题思路:

这是我所做的第一道差分约束的题目,以前看差分约束的时候看到那张矩阵连乘的图就不想看下去了(线代学的不好)

后来才知道与那个没什么毛线关系啊,其实就是给出m个关于n个元素的关系式,然后求解吗。。。。求解的方法是构造出不等式组(高中学过吧。。。。)然后求解,其实这个可以用最短路来求哦。。。。

就拿这道题来说吧,不等式组是。。。

假设Si=a1+a2+...ai

{

   s(i+n) - s(i-1)

   s(i+n) - s(i-1)>K

}

==>

{

   s(i+n)-s(i-1)<=k-1;

   s(i-1)-s(i+n)<=-k-1;

}

......然后构造图。。。

链式前向星。。。。。。。

#include
#include
using namespace std;
const int N = 109;
int n,m;
struct node{
   int to;
   int dis;
   int next;
};
int head[N],h;
node edg[N];
void add(int a,int b,int d)
{
    edg[h].to=b;
    edg[h].dis=d;
    edg[h].next=head[a];
    head[a]=h;
    h++;
}
bool in_q[N];
int cnt[N],dis[N];
queueq;
int spfa()
{
    int cur,k,v;
    while(!q.empty())
    {
        cur=q.front();
        q.pop();
        in_q[cur]=false;
        for(k=head[cur];k!=-1;k=edg[k].next)
        {
            v=edg[k].to;
            if(dis[v]>dis[cur]+edg[k].dis)
            {
                dis[v]=dis[cur]+edg[k].dis;
                if(!in_q[v])
                {
                    q.push(v);
                    in_q[v]==true;
                    cnt[v]++;
                    if(cnt[v]>n)
                         return 0;//需要清空队列的真正原因。。。。
                }
            }
        }
    }
    return 1;
}
void init()
{
    int i;
    for(i=0;i<=n;i++)
    {
        head[i]=-1;
        dis[i]=0;//既然只要判断其是否有负环的话。。。
        in_q[i]=false;
        cnt[i]=0;
    }
    h=0;
    while(!q.empty())//忘了讲队列清空了,我去。。。。
        q.pop();
}
int main()
{
    char buf[10];
    int i,u,v,d;
    while(scanf("%d",&n)&&n)
    {
       scanf("%d",&m);
       init();
       for(i=0;i



   

   

你可能感兴趣的:(图论)