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