关系运算图。。。(差分约束)

给出一有向图,图中每条边都被标上了关系运算符‘<’,‘>’,‘=’。现在要给图中每个顶点标上一个大于等于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 }

时间: 2024-10-14 05:38:47

关系运算图。。。(差分约束)的相关文章

【POJ3169 】Layout (认真的做差分约束)

Layout Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they ar

poj3169 最短路(差分约束)

题意:一个农夫有n头牛,他希望将这些牛按照编号 1-n排成一条直线,允许有几头牛站在同一点,但是必须按照顺序,有一些牛关系比较好,希望站的距离不超过某个值,而有一些牛关系不太好,所以希望站的距离大于等于某个值,问1号牛和n号牛之间的最远距离是多少. 差分约束的裸题,对于 d[v] - d[u] ≤ w 建立权值为 w 的单向边 e(u,v),对于 d[v] - d[u]  ≥ w 建立权值为 -w 的单向边 e(v,u),然后再根据牛必须按顺序排列建立权值为 0 的边 e(i+1,i),然后最短

ZOJ 2770 Burn the Linked Camp 差分约束

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2770 Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeate

zoj2770 Burn the Linked Camp --- 差分约束

有n个营地,每个营地至多容纳Ci人,给出m个条件:第i到第j个营地之间至少有k人. 问n个营地总共至少有多少人. 此题显然差分约束,要求最小值,则建立x-y>=z方程组,建图求最长路. 用d[i]表示[1,i]个帐篷中一共多少人,根据题意可得到不等关系: 1.0<=d[i]-d[i-1]<=C[i] 2.d[j]-d[i]>=k 此外,我们添加0为附加结点,则0到其他点也要建边. 再求解0为源点的最长路即可. 我的坑点是,判负环返回0,否则返回d[n]. 而d[n]本身就可能是0.

POJ 3159[差分约束]

题目链接:[http://poj.org/problem?id=3159] 题意:有N个小朋友,编号为1-N,每个小朋友将分的一些糖果,给出一些关系A.B.C .表示B最多比A多C个,然后问你盆友1和盆友N的糖果数最大差多少.保证有解. 题解:差分约束求最短距离:DIJ+对优化||SPAF+栈优化 #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using name

poj3159 Candies(差分约束,dij+heap)

poj3159 Candies 这题实质为裸的差分约束. 先看最短路模型:若d[v] >= d[u] + w, 则连边u->v,之后就变成了d[v] <= d[u] + w , 即d[v] – d[u] <= w. 再看题目给出的关系:b比a多的糖果数目不超过c个,即d[b] – d[a] <= c ,正好与上面模型一样, 所以连边a->b,最后用dij+heap求最短路就行啦. ps:我用vector一直TLE,后来改用前向星才过了orz... 1 #include&

zoj2770 差分约束问题

总的开说差分约束问题就是给出一系列不等式然后求问某一式子的最大值或者最小值. 差分约束问题详解: 比如有这样一组不等式: X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5                   不等式组(1) X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就

【差分约束】Layout

Layout TimeLimit: 1000MS   MemoryLimit: 65536K       Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The

差分约束 【bzoj2330】[SCOI2011]糖果

/*[bzoj2330][SCOI2011]糖果 2014年3月5日1,2761 Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求.幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求. Input 输入的第