1. 程式人生 > 其它 >[SCOI2011]糖果

[SCOI2011]糖果

差分約束的題

不多說

#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; }