poj2983&&poj1364

poj 1364

题目大意:

题目大意:n个数的一个序列,m个约数,si, ni, oi, ki, 代表了序列中第si个数到第si+ni个数的和大于或小于ki,gt = 大于,lt = 小于

问是否存在相悖的约束

 将这些约束条件转化为差分约束,不妨设sum[x] = S[1]+S[2]+....S[x],那么上面式子就可以转化为: 

     1. sum[si+ni] - T[si-1] > ki          2. sum[si+ni] - T[si-1] < ki  

     又差分约束系统的求解只能针对>=或<=,无法求解>的系统,还好ki是整数,可以很容易将<转化为<=  
     1. sum[si-1] - T[si+ni] <= -ki - 1    2. sum[si+ni] - T[si-1] <= ki - 1  

     剩下的就是普通的差分约束系统的求解了

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=70010;
int n,m;
struct node{
	int x,y,z,next;
}sa[N*4];int len=0,first[N];
void ins(int x,int y,int z)
{
	len++;
	sa[len].x=x;
	sa[len].y=y;
	sa[len].z=z;
	sa[len].next=first[x];
	first[x]=len;
}
queue<int> q;
int d[500010],ru[500010];
bool u[500010];
bool spfa()
{
    memset(d,0,sizeof(d));
    memset(ru,0,sizeof(ru));
    memset(u,true,sizeof(u));
    for(int i=0;i<=2*m;i++) q.push(i);
    while(!q.empty())
    {
        int x=q.front();
        for(int i=first[x];i!=-1;i=sa[i].next)
        {
            int y=sa[i].y;
            if(d[x]+sa[i].z>d[y])
            {
                d[y]=d[x]+sa[i].z;
                ru[i]++;if(ru[i]>m) return false;
                if(!u[y]) u[y]=true,q.push(y);
            }
        }
        q.pop();
        u[x]=false;
    }
    return true;
}
int main()
{
	while(1)
	{scanf("%d",&m);
	
	if(m==0) break;m++;
	scanf("%d",&n);
	int a,b,c;char s[7];
	memset(first,-1,sizeof(first));len=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%s%d",&a,&b,s,&c);
		a++;
		if(s[0]=='g')
		{
			ins(a-1,a+b,c+1);
		}
		else
		{
			ins(a+b,a-1,-c+1);
		}
	}
	if(!spfa()){printf("successful conspiracy\n");}
	else{printf("lamentable kingdom\n");}
	}
	

}


poj2983

题意:给出一些不等式,求是否存在可行解。

P  A  B  X得到的差分系统为

dist[A] - dist[B] >= X  &&  dist[A] - dist[B] <= X

等价于
dist[B] <= dist[A] - X  &&  dist[A] <= dist[B] + X


V  A  B得到的差分系统为
dist[A] >= dist[B] +1

等价于
dist[B] <= dist[A] -1 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int N=2000005;
int n,m;
struct node{
	int x,y,z,next;
}sa[N*4];int len=0,first[N];
void ins(int x,int y,int z)
{
	len++;
	sa[len].x=x;
	sa[len].y=y;
	sa[len].z=z;
	sa[len].next=first[x];
	first[x]=len;
}
queue<int> q;
int d[N],ru[N];
bool u[N];
bool spfa()
{
    memset(d,0,sizeof(d));
    memset(ru,0,sizeof(ru));
    memset(u,true,sizeof(u));
    for(int i=0;i<=n;i++) q.push(i);
    while(!q.empty())
    {
        int x=q.front();u[x]=false;
        for(int i=first[x];i!=-1;i=sa[i].next)
        {
            int y=sa[i].y;u[x]=false;
            if(d[x]+sa[i].z>d[y])
            {
                d[y]=d[x]+sa[i].z;
                ru[i]++;if(ru[i]>n) return false;
                if(!u[y]) u[y]=true,q.push(y);
            }
        }
        q.pop();
    }
    return true;
}
int main()
{
	while(scanf("%d %d",&n,&m)!=EOF)
	{
	int a,b,c;char s[7];
	bool tf=true;
	memset(first,-1,sizeof(first));len=0;
	for(int i=1;i<=m;i++)
	{
		scanf("%s",s);
		if(s[0]=='P')
		{
			scanf("%d%d%d",&a,&b,&c);
			ins(a,b,c);ins(b,a,-c);
		}
		else
		{
			if(a==b) tf=false;
			scanf("%d%d",&a,&b);
			ins(a,b,1);
		}
	}
	if(!spfa()||tf==false){printf("Unreliable\n");}
	else{printf("Reliable\n");}
	}
	

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值