[SCOI2011]糖果
阿新 • • 發佈:2021-07-17
差分約束的題
不多說
#include<bits/stdc++.h> using namespace std; const int N=1e5+7; int n,m; int head[N],nxt[N<<2],to[N<<2],edge[N<<2]; int d[N],flag[N],num[N]; long long sum; int _; void add(int x,int y,int z) { _++; to[_]=y; edge[_]=z; nxt[_]=head[x]; head[x]=_; return ; } queue<int > q; void Spfa(int x) {//跑個最長路 d[x]=0; q.push(x); flag[x]=1; num[x]++; while(!q.empty()) { int u=q.front(); q.pop(); flag[u]=0; for(int i=head[u];i;i=nxt[i]) { int v=to[i],z=edge[i];if(d[v]<d[u]+z) {//最長路鬆弛 d[v]=d[u]+z; if(!flag[v]) { q.push(v); flag[v]=1; num[v]++; if(num[v]>=n+1) {//判斷負環 cout<<"-1"; exit(0); } } } } } return ; } int main() { ios::sync_with_stdio(false); cin>>n>>m; memset(d,-1,sizeof(d)); while(m--) { int flag,q,w; cin>>flag>>q>>w; if(flag==1) {//一樣多 add(q,w,0); add(w,q,0); } else if(flag==2) { if(q==w) {//由於q的糖要<w的,所以二者不可相等 cout<<"-1"; return 0; } else add(q,w,1); } else if(flag==3) {//>=,最小=它既可 add(w,q,0); } else if(flag==4) {//必需多餘 if(q==w) { cout<<"-1"; return 0; } add(w,q,1); } else if(flag==5) { add(q,w,0);//不多於 } } //有資料卡正序 for(int i=n;i>=1;i--) add(0,i,1); //必須要比起始虛擬源點要大(題面要求每個人都有糖 Spfa(0); for(int i=n;i>=1;i--) sum+=d[i]; cout<<sum; return 0; }