n<=1000个数,从小到大,给m1<=10000条描述两个数相差不超过多少,m2<=10000条描述两个数相差至少多少,求1到n最大距离,无解-1无穷大-2。
裸的差分约束,spfa判负环。
差分约束口诀!大小短,小大长!(最大值,用≤式子,写最短路,后面同理)
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 //#include<iostream> 6 using namespace std; 7 8 int n,m1,m2; 9 #define maxn 1011 10 #define maxm 20011 11 struct Edge{int to,v,next;}; 12 const int inf=0x3f3f3f3f; 13 int x,y,v; 14 struct Graph 15 { 16 Edge edge[maxm]; 17 int first[maxn],le; 18 Graph() {memset(first,0,sizeof(first));le=2;} 19 void in(int x,int y,int v) 20 { 21 Edge &e=edge[le]; 22 e.to=y;e.v=v; 23 e.next=first[x]; 24 first[x]=le++; 25 } 26 int que[maxn],head,tail,ins[maxn],dis[maxn];bool vis[maxn]; 27 int spfa(int s,int t) 28 { 29 que[head=(tail=1)-1]=s; 30 memset(vis,0,sizeof(vis));vis[s]=1; 31 memset(ins,0,sizeof(ins)); 32 for (int i=1;i<=n;i++) dis[i]=inf;dis[s]=0; 33 while (head!=tail) 34 { 35 const int now=que[head++]; 36 if (head==maxn) head=0; 37 vis[now]=0; 38 ins[now]++; 39 if (ins[now]>n) return -1; 40 for (int i=first[now];i;i=edge[i].next) 41 { 42 Edge &e=edge[i]; 43 if (dis[e.to]>dis[now]+e.v) 44 { 45 dis[e.to]=dis[now]+e.v; 46 if (!vis[e.to]) 47 { 48 vis[e.to]=1; 49 que[tail++]=e.to; 50 if (tail==maxn) tail=0; 51 } 52 } 53 } 54 } 55 return dis[t]==inf?-2:dis[t]; 56 } 57 }g; 58 int main() 59 { 60 scanf("%d%d%d",&n,&m1,&m2); 61 for (int i=1;i<=m1;i++) 62 { 63 scanf("%d%d%d",&x,&y,&v); 64 g.in(min(x,y),max(x,y),v); 65 } 66 for (int i=1;i<=m2;i++) 67 { 68 scanf("%d%d%d",&x,&y,&v); 69 g.in(max(x,y),min(x,y),-v); 70 } 71 printf("%d ",g.spfa(1,n)); 72 return 0; 73 }