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

     

     

  • 相关阅读:
    kde下sudo出现cannot connect to xserver解决方法
    windows版本的Emacs 无法显示图片的解决方法
    Ubuntu12.04安装VMwareWorkstation8.0.2591240.x86_64
    在Emacs调试JAVA程序,使用GUD模式
    配置SQL Server Session方法(1)
    C#泛型列表List<T>基本用法总结
    VC++的MFC中 获取选中静态文本的内容
    用P3P header解决IE下iframe跨域访问时候session丢失的问题
    ROW_NUMBER()用法(转)
    VC 中与字符串相关的宏 _T、TEXT,_TEXT、L 的作用
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122871.html
Copyright © 2020-2023  润新知