您的位置:首页 > 其它

poj 2983 中等的差分约束

2013-12-14 20:05 375 查看
对于差分约束题目的关键在于怎么找到问题约束的条件,这也是难点

对于本题主要有两个条件


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

{

    int
to;

    int w;

    int
next;

}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))

   
   
   
   
    {

   
   
   
   
   
    return
0;

   
   
   
   
    }

   
   
   
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: