⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪(1)(2)(3)(4)(5) A=B A<B A≥B A>B A≤B
{
(
1
)
A
=
B
(
2
)
A
<
B
(
3
)
A
≥
B
(
4
)
A
>
B
(
5
)
A
≤
B
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪(1)(2)(3)(4)(5) A−B≥0,B−A≥0 B−A≥1 A−B≥0 A−B≥1 B−A≥0
{
(
1
)
A
−
B
≥
0
,
B
−
A
≥
0
(
2
)
B
−
A
≥
1
(
3
)
A
−
B
≥
0
(
4
)
A
−
B
≥
1
(
5
)
B
−
A
≥
0
- 对应连边即可。
- 因为每个小朋友手上都要有糖果,增加一个起点向其它所有点连一条权值为1的边。
- 无解的情况有两种:
- 图中存在负环(用
DFS
D
F
S
版
SPFA
S
P
F
A
判断)。
- 出现了形如
A>A
A
>
A
或
A<A
A
<
A
的不等式。
- 然而用(sang)心(xin)良(bing)苦(kuang)的出题人设了点卡普通
SPFA
S
P
F
A
,仿佛还要加
SLF
S
L
F
优化(设要加入的节点是
j
j
,队首元素为 i,若
dist(j)≤dist(i)
d
i
s
t
(
j
)
≤
d
i
s
t
(
i
)
,则将
j
j
插入队首,否则插入队尾,可以用 STL 或者手写循环队列模拟)。
Code
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
namespace inout
{
const int S = 1 << 20;
char frd[S], *ihed = frd + S;
const char *ital = ihed;
inline char inChar()
{
if (ihed == ital)
fread(frd, 1, S, stdin), ihed = frd;
return *ihed++;
}
inline int get()
{
char ch; int res = 0; bool flag = false;
while (!isdigit(ch = inChar()) && ch != '-');
(ch == '-' ? flag = true : res = ch ^ 48);
while (isdigit(ch = inChar()))
res = res * 10 + ch - 48;
return flag ? -res : res;
}
};
using namespace inout;
typedef long long ll;
const int N = 1e5 + 5, M = N << 3;
const int Maxn = 0x3f3f3f3f;
bool vis[N]; int dis[N], h[M], n, k, m; ll Ans;
struct Edge
{
int to, cst; Edge *nxt;
}p[M], *T = p, *lst[N];
inline void Link(int x, int y, int z)
{
(++T)->nxt = lst[x]; lst[x] = T; T->to = y; T->cst = z;
}
inline bool dfs_Spfa(int x)
{
vis[x] = true; int y;
for (Edge *e = lst[x]; e; e = e->nxt)
if (dis[y = e->to] > dis[x] + e->cst)
{
dis[y] = dis[x] + e->cst;
if (vis[y] || dfs_Spfa(y)) return true;
}
return vis[x] = false;
}
inline void bfs_Spfa()
{
memset(vis, false, sizeof(vis));
memset(dis, Maxn, sizeof(dis));
dis[h[1] = 0] = 0; int t = 0, w = 1, x, y;
while (t != w)
{
if (++t == M) t = 0;
vis[x = h[t]] = false;
for (Edge *e = lst[x]; e; e = e->nxt)
if (dis[y = e->to] > dis[x] + e->cst)
{
dis[y] = dis[x] + e->cst;
if (!vis[y])
{
if (dis[y] > dis[h[t + 1]])
{
if (++w == M) w = 0;
vis[h[w] = y] = true;
}
else
{
vis[h[t] = y] = true;
if (!t--) t = M - 1;
}
}
}
}
}
int main()
{
n = get(); m = get(); int k, x, y;
while (m--)
{
k = get(); x = get(); y = get();
switch (k)
{
case 1: Link(x, y, 0); Link(y, x, 0); break;
case 2: if (x == y) return puts("-1"), 0; Link(x, y, -1); break;
case 3: Link(y, x, 0); break;
case 4: if (x == y) return puts("-1"), 0; Link(y, x, -1); break;
case 5: Link(x, y, 0); break;
}
}
for (int i = 1; i <= n; ++i) Link(0, i, -1);
bool flag = false;
for (int i = 1; i <= n && !(flag = dfs_Spfa(i)); ++i);
if (flag) return puts("-1"), 0;
bfs_Spfa();
for (int i = 1; i <= n; ++i) Ans += (ll)dis[i];
cout << -Ans << endl;
return 0;
}