很久以前学的差分约束,基本忘了,复习一下
a<=b+c,ins(b,a,c)是最短链,每个元素最大
a>=b+c,ins(b,a,c)是最长链,每个元素最小
#include<bits/stdc++.h> #pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=1e5+5; int n,m,s; struct EDGE{int v,ne;double w;}e[maxn<<1]; int h[maxn],cnt=0; inline void ins(int u,int v,int w){ cnt++; e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt; } int q[maxn],head,tail,inq[maxn],num[maxn],d[maxn]; inline void lop(int &x){if(x==maxn)x=1;} bool spfa(int s){ for(int i=1;i<=n;i++)d[i]=-inf; head=tail=0; memset(inq,0,sizeof inq); memset(num,0,sizeof num); for(int i=1;i<=n;i++)q[tail++]=i,inq[i]=1,d[i]=1; while(head!=tail){ int u=q[head++];inq[u]=0;lop(head); for(int i=h[u];i;i=e[i].ne){ int v=e[i].v,w=e[i].w; if(d[v]<d[u]+w){ d[v]=d[u]+w; if(!inq[v]){ inq[v]=1,q[tail++]=v,lop(tail); if(++num[v]>n)return 1; } } } } return 0; } int main(){ scanf("%d%d",&n,&m); s=0; for(int i=1,x,a,b;i<=m;i++){ scanf("%d%d%d",&x,&a,&b); if(x==1)ins(a,b,0),ins(b,a,0); else if(x==2){if(a==b){puts("-1");return 0;}ins(a,b,1);} else if(x==3){ins(b,a,0);} else if(x==4){if(a==b){puts("-1");return 0;}ins(b,a,1);} else ins(a,b,0); } if(spfa(s))puts("-1"); else{ ll ans=0; for(int i=1;i<=n;i++)ans+=d[i]; printf("%lld ",ans); } }