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

    return1;
}

int min(int x , int y)
{
    if(x <y)  return x;
    returny;
}

int main()
{
   while(scanf("%d %d" , &n , &m ) != EOF)
    {
      getchar();
       int i , x ,y , z , j = 0 , g , h;
       charc;
      init();
       for(i = 1; i<= m; i++)  //建立图
       {
          scanf("%c" ,&c);
          if(c =='P')
          {
             scanf("%d %d%d" , &x , &y , &z);
             edge[j].to =y;
             edge[j].w =z;
            edge[j++].next = head[x];
             head[x] =j-1;

             edge[j].to =x;
             edge[j].w =-z;
            edge[j++].next = head[y];
             head[y] =j-1;
         //    g =find(x) , h = find(y);
         //    p[g] =h;
          }
          else
          {
             scanf("%d%d" , &x , &y);
             edge[j].to =x;
             edge[j].w =-1;
            edge[j++].next = head[y];
             head[y] =j-1;
         //    g =find(x) , h = find(y);
         //    p[g] =h;
          }

         getchar();
         
         
       }

       for(i = 1; i<= n; i++)  //加入一个源点 0
       {
          edge[j].to =i;
          edge[j].w =1;
         edge[j++].next = head[0];
          head[0] =j-1;
       }

       x =SPFA(0);
       if(x !=0)
         cout<<"Reliable"<<endl;
       elsecout<<"Unreliable"<<endl;
      


      
    }
    return0;
}


0 0
原创粉丝点击