poj 2983 中等的差分约束
来源:互联网 发布:手机怎样淘宝购物 编辑:程序博客网 时间:2024/05/17 12:47
对于差分约束题目的关键在于怎么找到问题约束的条件,这也是难点
对于本题主要有两个条件:
1. 边长确定,即xi - xj = b; 可以转化成 xi -xj <= b 和 xi - xj >=b (即 xj - xi <= -b).
2. 边长不定,xi - xj >= 1; 可以转化成 xj - xi <= -1;
再通过这两个条件建图 , 然后再用SPFA算法就行了 , 由于我们所建的图不一定是一个连通图 ,
所以我们加一个源点 , 这个源点到其他每一个点都有一条边权为1的边 ;
或则用并查集来区分这个图的基图有多个个连通分量 ,我们然后再分别对每个连通分量调用一次SPFA
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1010
#define INF 0xfffffff
int dist[maxn] , n , m , k;
int p[maxn];
struct node
{
intto;
int w;
intnext;
}edge[201005];
int head[maxn];
void init()
{
memset(head, -1 , sizeof(head));
for(int i =1; i <= n; i++)
p[i] =i;
}
int SPFA(int xy)
{
int i ,pre[maxn] , vis[maxn];
queueq1;
for(i = 0; i<= n; i++)
dist[i] =INF;
memset(vis ,0 , sizeof(vis));
memset(pre ,0 , sizeof(pre));
vis[xy] +=1;
dist[xy] =0;
q1.push(xy);
while(!q1.empty())
{
int u =q1.front(); q1.pop();
pre[u] =0;
//cout<<u<<endl;
for(i =head[u]; i != -1 ; i = edge[i].next)
{
//cout<<i<<endl;
int x =edge[i].to;
if(dist[x]> dist[u]+edge[i].w)
{
dist[x] =dist[u]+edge[i].w;
if(!pre[x])
{
pre[x] = 1 ,q1.push(x);
if(++vis[x]> (n+1))
{
return0;
}
对于本题主要有两个条件:
1. 边长确定,即xi - xj = b; 可以转化成 xi -xj <= b 和 xi - xj >=b (即 xj - xi <= -b).
2. 边长不定,xi - xj >= 1; 可以转化成 xj - xi <= -1;
再通过这两个条件建图 , 然后再用SPFA算法就行了 , 由于我们所建的图不一定是一个连通图 ,
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1010
#define INF
int dist[maxn] , n , m , k;
int p[maxn];
struct node
{
}edge[201005];
int head[maxn];
void init()
{
}
int SPFA(int xy)
{