zoukankan      html  css  js  c++  java
  • 关系运算图。。。(差分约束)

    给出一有向图,图中每条边都被标上了关系运算符‘<’,‘>’,‘=’。现在要给图中每个顶点标上一个大于等于0,小于等于k的某个整数使所有边上的符号得到满足。若存在这样的k,则求最小的k,若任何k都无法满足则输出NO。
    例如下表中最小的k为2。
    结点1>结点2
    结点2>结点3
    结点2>结点4
    结点3=结点4
    如果存在这样的k,输出最小的k值;否则输出‘NO’。

    INTPUT:

    共二行,第一行有二个空格隔开的整数n和m。n表示G的结点个数,m表示G的边数,其中1<=n<=1000, 0<=m<=10000。全部结点用1到n标出,图中任何二点之间最多只有一条边,且不存在自环。
    第二行共有3m个用空格隔开的整数,第3i-2和第3i-1(1<=i<=m)个数表示第i条边的顶点。第3i个数表示第i条边上的符号,其值用集合{-1,0,1}中的数表示:-1表示‘<’, 0 表示‘=’, 1表示‘>’。

    4 4
    1 2 -1 2 3 0 2 4 -1 3 4 -1

    OUTPUT:

    仅一行,如无解则输出‘NO’;否则输出最小的k的值。

    2



    这道题需要另一个技能————差分约束。



    思路:

    题中有三个约束条件:a<b,a=b,a>b;

    但实际上只有两种:a<b,a=b;

    所以,对于a<b,我们就让a向b有一条权值为1的边。a>b,就让b到a有一条权值为1的边。

    a=b,a到b有一条权值为0的边。

    然后,SPFA求最大路。

    cpp:

     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<iomanip>
     8 #include<queue>
     9 using namespace std;
    10 int n,m;
    11 int len=0,dis[30000],lin[30000];
    12 int id[30000];
    13 struct node
    14 {
    15     int x,y,v;
    16 }e[30000];
    17 
    18 void init(int xx,int yy,int vv)
    19 {
    20     e[++len].y=lin[xx];lin[xx]=len;e[len].x=yy;e[len].v=vv;
    21 }
    22 
    23 bool pai()
    24 {
    25     /*memset(dis,0,sizeof(dis));*/
    26     int q[30000];
    27     int head=0,tail=0;
    28     int maxx=0;
    29     for(int i=1;i<=n;i++)
    30         if(id[i]==0)    q[++tail]=i;
    31     while(head<=tail)
    32     {
    33         int tn=q[++head];
    34         int te=lin[tn];
    35         for(int i=te;i;i=e[i].y)
    36         {
    37             int tmp=e[i].x;
    38             id[tmp]--;
    39             if(id[e[i].x]<0)
    40                 return 1;
    41             dis[tmp]=max(dis[tmp],dis[q[head]]+e[i].v);
    42             if(id[e[i].x]==0)
    43                 q[++tail]=e[i].x;
    44         }
    45     }
    46     sort(dis+1,dis+1+n);
    47     if(dis[n]<=maxx)
    48         return 1;
    49     return 0;
    50 }
    51 
    52 int main()
    53 {
    54     freopen("2.in","r",stdin);
    55     freopen("2.out","w",stdout);
    56     //ios::sync_with_stdio(false);
    57     cin>>n>>m;
    58     memset(e,0,sizeof(e));
    59     memset(id,0,sizeof(id));
    60     /*for(int i=1;i<=n;i++)
    61         init(0,i,0);*/
    62     for(int i=1;i<=m;i++)
    63     {
    64         int xx,yy,vv;
    65         cin>>xx>>yy>>vv;
    66         if(vv==0)
    67         {
    68             init(xx,yy,0);
    69             id[yy]++;
    70         }
    71         else if(vv==1)
    72         {
    73             init(yy,xx,1);
    74             id[xx]++;
    75         }
    76         else if(vv==-1)
    77         {
    78             init(xx,yy,1);
    79             id[yy]++;
    80         }
    81     }
    82     if(pai())
    83         cout<<"NO"<<endl;
    84     else
    85     {
    86         cout<<dis[n]<<endl;
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    php关联Apache和nginx
    /etc/profile
    snmp配置
    snmpwalk
    redis主从
    redis安装
    计算真实可用内存
    分类样本不均
    pandas apply 添加进度条
    linux 单次定时任务
  • 原文地址:https://www.cnblogs.com/zyker/p/5943201.html
Copyright © 2011-2022 走看看