现学了差分约束。。。
若b>=a+1则a->b:1求最长路。
数据有环,所以不要源点。
为什么要把dis初始化成1?因为每个小朋友至少分到1个。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 100500 #define maxe 400500 using namespace std; struct edge { int v,w,nxt; }e[maxe]; int n,k,x,a,b,g[maxv],nume=0,dis[maxv],cnt[maxv]; queue <int> q; bool vis[maxv]; void addedge(int u,int v,int w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } bool spfa() { for (int i=1;i<=n;i++) { dis[i]=1; q.push(i); vis[i]=true; cnt[i]=1; } while (!q.empty()) { int head=q.front();q.pop();vis[head]=false; for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if (dis[v]<dis[head]+e[i].w) { dis[v]=dis[head]+e[i].w; if (++cnt[v]>=n) return 0; else if (!vis[v]) { vis[v]=true; q.push(v); } } } } return 1; } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=k;i++) { scanf("%d%d%d",&x,&a,&b); if (x==1) {addedge(a,b,0);addedge(b,a,0);} else if (x==2) { if (a==b) {printf("-1\n");return 0;} else addedge(a,b,1); } else if (x==3) addedge(b,a,0); else if (x==4) { if (a==b) {printf("-1\n");return 0;} else addedge(b,a,1); } else addedge(a,b,0); } if (spfa()) { long long ans=0; for (int i=1;i<=n;i++) ans+=dis[i]; printf("%lld\n",ans); } else printf("-1\n"); return 0; }