题解 P3275 【[SCOI2011]糖果】
程序员文章站
2024-03-23 15:46:16
...
清深夏令营机考压轴题,对差分约束的认识还是不够深刻,算法写出来了图没建对,/(ㄒoㄒ)/~~
#define inf 0x3f3f3f3f
#define ll long long
#define vec vector<int>
#define P pair<int,int>
#define MAX 100005
int N, K, x, a, b, vis[MAX], cnt[MAX], dist[MAX];
struct edge {
int v, c;
edge(int a = 0, int b = 0) { v = a, c = b; }
};
vector<edge>G[MAX];
void addEdge(int x, int a, int b) {
if (x == 1)G[a].push_back(edge(b, 0)), G[b].push_back(edge(a, 0));
else if (x == 2)G[a].push_back(edge(b, 1));
else if (x == 3)G[b].push_back(edge(a, 0));
else if (x == 4)G[b].push_back(edge(a, 1));
else G[a].push_back(edge(b, 0));
}
bool spfa(int s) {
memset(vis, 0, sizeof(vis));
memset(cnt, 0, sizeof(cnt));
fill(dist, dist + MAX, 0);
queue<int> q; q.push(s); vis[s] = 1; dist[s] = 0;
while (!q.empty()) {
int u = q.front(); q.pop(); cnt[u]++; vis[u] = 0;
if (cnt[u] == N)return false;
for (int i = 0; i < G[u].size(); i++) {
edge e = G[u][i];
if (dist[u] + e.c > dist[e.v]) {
dist[e.v] = dist[u] + e.c;
if (!vis[e.v]) {
vis[e.v] = 1;
q.push(e.v);
}
}
}
}
return true;
}
int main() {
while (scanf("%d %d", &N, &K) != EOF) {
for (int i = 0; i <= N; i++) {
G[i].clear();
if (i != 0)G[0].push_back(edge(i, 1));//超级源点
}
int sign = 1;
for (int i = 0; i < K; i++) {
scanf("%d %d %d", &x, &a, &b);
if (x == 2 || x == 4) {
if (a == b) { sign = 0; }
}
addEdge(x, a, b);
}
if (!sign) { cout << -1 << endl; continue; }
if (!spfa(0))cout << -1 << endl;
else {
ll mi = inf, res = 0;
for (int i = 1; i <= N; i++) {
if (dist[i] < mi)mi = dist[i];
res += dist[i];
}
if (mi < 0)
res += (-mi + 1)*N;
cout << res << endl;
}
}
}