# BZOJ 2330 糖果 差分约束求最小值

https://www.lydsy.com/JudgeOnline/problem.php?id=2330

差分约束系统求最大值时，构造边按照：d[v] - d[u] <=  Edge[u][v] (u->v连边)，求解时按照最短路求解（也就是松弛的时候按照原来的方式进行松弛）

  1 #include<bits/stdc++.h>
2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf
3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数，会超时
4 #define Min(a, b) ((a) < (b) ? (a) : (b))
5 #define Mem(a) memset(a, 0, sizeof(a))
6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1))
7 #define MID(l, r) ((l) + ((r) - (l)) / 2)
8 #define lson ((o)<<1)
9 #define rson ((o)<<1|1)
10 #define Accepted 0
12 using namespace std;
14 {
15     int x=0,f=1;char ch=getchar();
16     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
17     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 typedef long long ll;
21 const int maxn = 1000000 + 10;
22 const int MOD = 1000000007;//const引用更快，宏定义也更快
23 const ll INF = 1e12 + 7;
24 const double eps = 1e-6;
25
26 struct edge
27 {
28     ll u, v;
29     ll w;
30     ll next;
31 };
32 edge a[maxn];
34 void addedge(ll u, ll v, ll w)
35 {
36     a[node].u = u;
37     a[node].v = v;
38     a[node].w = w;
41 }
42
43 ll cnt[maxn];
44 bool vis[maxn];
45 ll d[maxn];
46 ll n;
47 bool SPFA(ll u)
48 {
49     queue<ll>q;
50     memset(vis, 0, sizeof(vis));
51     memset(cnt, 0, sizeof(cnt));
52     for(int i = 1; i <= n; i++)d[i] = -INF;//赋值成最小值 来求解最长路
53     d[u] = 0;
54     vis[u] = 1;
55     q.push(u);
56     while(!q.empty())
57     {
58         ll u = q.front();
59         q.pop();
60         vis[u] = 0;
61         for(ll i = head[u]; i != -1; i = a[i].next)
62         {
63             edge& e = a[i];
64             if(d[e.v] < d[u] + e.w)//求最长路松弛符号改变
65             {
66                 d[e.v] = d[u] + e.w;
67                 if(!vis[e.v])
68                 {
69                     q.push(e.v);
70                     vis[e.v] = 1;
71                     if(++cnt[e.v] >= n)return false;
72                 }
73             }
74         }
75     }
76     return true;
77 }
78 int main()
79 {
81     ll k, x, a, b;
82     scanf("%lld%lld", &n, &k);
83     for(ll i = n; i >= 1; i--)addedge(0, i, 0);
84     bool flag = 0;
85     while(k--)
86     {
87         scanf("%lld%lld%lld", &x, &a, &b);
88         if(x == 1)
89         {
92         }
93         else if(x == 2)
94         {
95             if(a == b)flag = 1;
97         }
98         else if(x == 3)
99         {
101         }
102         else if(x == 4)
103         {
104             if(a == b)flag = 1;
106         }
107         else
108         {
110         }
111     }
112     if(!flag && SPFA(0))
113     {
114         ll ans = 0;
115         for(ll i = 1; i <= n; i++)ans += d[i] + 1;//加上最开始的1
116         printf("%lld\n", ans);
117     }
118     else
119     {
120         printf("-1\n");
121     }
122     return Accepted;
123 }

posted @ 2018-09-24 23:46  _努力努力再努力x  阅读(312)  评论(0编辑  收藏  举报