zoukankan      html  css  js  c++  java
  • POJ2983Is the Information Reliable

    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1307201897

     

    题目大意:

    给出M个表达式,判断这些信息是否可靠。

     

    解题思路:

    差分约束+Bellman-Ford(建议用优化的Bellman-Ford

    dist[i]为超级源点到i点的距离,则

    建立<=的差分系统:

     

    由于P  A  B  X 指“确定AB的距离(边权)为X

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

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

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

     if(dist[B] > dist[A]-X) 松弛:dist[B] = dist[A]-X


    由于 V  A  B指“只知道AB的距离(边权)至少为1

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

    等价于
    dist[B] <= dist[A] -1
    if(dist[B] > dist[A] -1) 松弛:dist[B] = dist[A] -1


    注意:

    (1)       建立<=的差分系统,就必须求最短路(Bellman-Ford算法)。

    而信息是否可靠,就是判断图中是否存在负权回路 (也是利用 Bellman-Ford判断)

    (2)       由于最坏有10W组不等式,经实测用scanf输入比cin要节省1500ms

    (3)       经实测用优化Bellman-Ford算法 普通Bellman-Ford算法 2000ms

     

     1 /*差分约束+优化Bellman*/
    2
    3 //Memory Time
    4 //2596K 485MS
    5
    6 #include <iostream>
    7 using namespace std;
    8
    9 const int inf=1000000000;
    10
    11 class
    12 {
    13 public:
    14 int s,e;
    15 }edge[200001];
    16
    17 int N; //太空站数目
    18 int M; //tips数
    19
    20 int dist[1001]; //源点到各点的距离
    21 int w[200001]; //边权
    22
    23 int main(int i,int j)
    24 {
    25 while(cin>>N>>M)
    26 {
    27 memset(dist,0,sizeof(dist)); //初始化源点到各点的距离
    28 int pe=0;
    29
    30 for(i=0;i<M;i++)
    31 {
    32 char pv;
    33 int a,b,x;
    34
    35 getchar(); //吃掉回车
    36 scanf("%c",&pv); //由于要频繁输入,用scanf比cin要快1500ms
    37
    38 if(pv=='P') //清晰边权,即A、B间距离确定,建立双向边
    39 {
    40 scanf("%d%d%d",&a,&b,&x);
    41 edge[pe].s=a;
    42 edge[pe].e=b;
    43 w[pe++]=x;
    44 edge[pe].s=b;
    45 edge[pe].e=a;
    46 w[pe++]=-x;
    47 }
    48 else if(pv=='V') //模糊边权,即A、B间距离不确定,建立单向边
    49 {
    50 scanf("%d%d",&a,&b);
    51 edge[pe].s=a;
    52 edge[pe].e=b;
    53 w[pe++]=1;
    54 }
    55 }
    56
    57 /*Bellman-Ford*/
    58
    59 bool sign; //用于Bellman-Ford算法优化
    60 for(j=0;j<N;j++)
    61 {
    62 sign=false;
    63 for(i=0;i<pe;i++)
    64 if(dist[ edge[i].e ] > dist[ edge[i].s ] - w[i])
    65 {
    66 dist[ edge[i].e ] = dist[ edge[i].s ] - w[i];
    67 sign=true;
    68 }
    69 if(!sign)//若dist没有任何改变,则以后也不会改变,可以直接退出循环
    70 break;
    71 }//循环n次后若flag == false 说明有负权回路,或者权值矛盾
    72
    73 if(sign)
    74 cout<<"Unreliable"<<endl; //存在负权环
    75 else
    76 cout<<"Reliable"<<endl; //不存在负权环
    77
    78 }
    79 return 0;
    80 }

    =======华丽的分割线=======

     1 /*差分约束+无优化Bellman*/
    2
    3
    4 //Memory Time
    5 //2596K 2438MS
    6
    7 #include<iostream>
    8 using namespace std;
    9
    10 const int inf=1000000000;
    11
    12 class
    13 {
    14 public:
    15 int s,e;
    16 }edge[200001];
    17
    18 int N; //太空站数目
    19 int M; //tips数
    20
    21 int dist[1001]; //源点到各点的距离
    22 int w[200001]; //边权
    23
    24 int main(int i,int j)
    25 {
    26 while(cin>>N>>M)
    27 {
    28 memset(dist,0,sizeof(dist)); //初始化源点到各点的距离
    29 int pe=0;
    30
    31 for(i=0;i<M;i++)
    32 {
    33 char pv;
    34 int a,b,x;
    35
    36 getchar(); //吃掉回车
    37 scanf("%c",&pv);
    38 if(pv=='P') //清晰边权,即A、B间距离确定,建立双向边
    39 {
    40 scanf("%d%d%d",&a,&b,&x);
    41 edge[pe].s=a;
    42 edge[pe].e=b;
    43 w[pe++]=x;
    44 edge[pe].s=b;
    45 edge[pe].e=a;
    46 w[pe++]=-x;
    47 }
    48 else if(pv=='V') //模糊边权,即A、B间距离不确定,建立单向边
    49 {
    50 scanf("%d%d",&a,&b);
    51 edge[pe].s=a;
    52 edge[pe].e=b;
    53 w[pe++]=1;
    54 }
    55 }
    56
    57 /*Bellman-Ford*/
    58
    59 /*Relax*/
    60
    61 for(j=0;j<N;j++)
    62 for(i=0;i<pe;i++)
    63 if(dist[ edge[i].e ] > dist[ edge[i].s ] - w[i])
    64 dist[ edge[i].e ] = dist[ edge[i].s ] - w[i];
    65
    66 /*Judge the Negative Circle*/
    67
    68 bool sign=false;
    69 for(i=0;i<pe;i++)
    70 if(dist[ edge[i].e ] > dist[ edge[i].s ] - w[i])
    71 {
    72 sign=true;
    73 break;
    74 }
    75
    76 if(sign)
    77 cout<<"Unreliable"<<endl; //存在负权环
    78 else
    79 cout<<"Reliable"<<endl; //不存在负权环
    80 }
    81 return 0;
    82 }

     

     

  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122871.html
Copyright © 2011-2022 走看看