poj 2883——Points

差分约束

注意点是要建立一个超级原点 防止有多个分图出现

#include<queue>
#include<iostream>
#include<cstdio>
using namespace std;
#define INF 10000001
#define esp 1
int n,m;
int head[2][30015],v[2][30015],next[2][30015];
double w[2][30015];
double dis[1005];
int input[1505],output[1505];
int cnt[2];
void add(int k,int a,int b,double c)
{
	v[k][cnt[k]]=b;
	w[k][cnt[k]]=c;
	next[k][cnt[k]]=head[k][a];
	head[k][a]=cnt[k]++;
}
bool spfa(int k)
{
	for(int i=1;i<=n;i++)
		dis[i]=-INF;
	memset(input,0,sizeof(input));
	memset(output,0,sizeof(output));
	queue<int> q;
	q.push(0);
	dis[0]=0;
	input[0]=1;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		input[u]=0;
		output[u]++;
		if(output[u]>n)
			return 0;
		for(int i=head[k][u];i!=-1;i=next[k][i])
			if(dis[v[k][i]]<dis[u]+w[k][i])
			{
				dis[v[k][i]]=dis[u]+w[k][i];
				if(!input[v[k][i]])
				{
					q.push(v[k][i]);
					input[v[k][i]]=1;
				}
			}
	}
	return 1;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(head,-1,sizeof(head));
		memset(cnt,0,sizeof(cnt));
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		{
			add(0,0,i,0);
			add(1,0,i,0);
		}
		for(int i=0;i<m;i++)
		{
			int x,z;
			char y[10];
			scanf("%d%s%d",&x,&y,&z);
			if(y[0]=='N'&&y[1]=='E')
			{
				add(0,x,z,esp);//zy
				add(1,x,z,esp);//sx
				continue;
			}
			if(y[0]=='N'&&y[1]=='W')
			{
				add(0,z,x,esp);
				add(1,x,z,esp);
				continue;
			}
			if(y[0]=='N'&&y[1]=='\0')
			{
				add(0,x,z,0);
				add(0,z,x,0);
				add(1,x,z,esp);
				continue;
			}
			if(y[0]=='S'&&y[1]=='E')
			{
				add(0,x,z,esp);
				add(1,z,x,esp);
				continue;
			}
			if(y[0]=='S'&&y[1]=='W')
			{
				add(0,z,x,esp);
				add(1,z,x,esp);
				continue;
			}
			if(y[0]=='S'&&y[1]=='\0')
			{
				add(0,x,z,0);
				add(0,z,x,0);
				add(1,z,x,esp);
				continue;
			}
			if(y[0]=='E')
			{
				add(0,x,z,esp);
				add(1,x,z,0);
				add(1,z,x,0);	
				continue;
			}
			if(y[0]=='W')
			{
				add(0,z,x,esp);
				add(1,x,z,0);
				add(1,z,x,0);	
				continue;
			}
		}
		if(spfa(0)&&spfa(1))
			cout<<"POSSIBLE"<<endl;
		else
			cout<<"IMPOSSIBLE"<<endl;
		
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值