[spfa][差分约束] Bzoj 2330 糖果
题解
- 这很显然就是差分约束系统,然后跑最长路就好了
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <queue> 5 #define ll long long 6 using namespace std; 7 const int N=300010; 8 int n,k,cnt,head[N],dis[N],tot[N]; 9 ll ans; 10 bool vis[N]; 11 queue<int>Q; 12 struct edge {int to,from,v;}e[N]; 13 void insert(int x,int y,int v) { e[++cnt].to=y,e[cnt].from=head[x],e[cnt].v=v,head[x]=cnt; } 14 int read() 15 { 16 char ch=getchar(); int x=0; 17 while (ch<'0'||ch>'9') ch=getchar(); 18 while (ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar(); 19 return x; 20 } 21 int main() 22 { 23 n=read(),k=read(); 24 for (int i=1,x,a,b;i<=k;i++) 25 { 26 x=read(),a=read(),b=read(); 27 if (x==1) insert(a,b,0),insert(b,a,0); 28 if (x==2) 29 { 30 if (a==b) { printf("-1"); return 0; } 31 insert(a,b,1); 32 } 33 if (x==3) insert(b,a,0); 34 if (x==4) 35 { 36 if (a==b) { printf("-1"); return 0; } 37 insert(b,a,1); 38 } 39 if (x==5) insert(a,b,0); 40 } 41 for (int i=n;i>=1;i--) insert(0,i,1); 42 vis[0]=1,Q.push(0); 43 while (!Q.empty()) 44 { 45 int u=Q.front(); Q.pop(),vis[u]=0; 46 if (tot[u]==n-1) { printf("-1"); return 0; } 47 tot[u]++; 48 for (int i=head[u];i;i=e[i].from) 49 if (dis[e[i].to]<dis[u]+e[i].v) 50 { 51 dis[e[i].to]=dis[u]+e[i].v; 52 if (!vis[e[i].to]) Q.push(e[i].to),vis[e[i].to]=1; 53 } 54 } 55 for (int i=1;i<=n;i++) ans+=dis[i]; 56 printf("%lld",ans); 57 }