[Luogu 3275] SCOI2011 糖果
阿新 • • 發佈:2018-11-03
[Luogu 3275] SCOI2011 糖果
第一道差分約束。感謝 AZe。
我的理解是根據一些不等關係建一個圖,在圖上邊跑一個最長路(有時候是最短路)。
因為可能存在負環,所以必須用 SPFA!
好神奇啊,圖論好強強啊。
然而 Capella 慘慘,用上了 0 號節點卻從 1 開始初始化鄰接表,導致 for 出不去了,就因為這個調了一個晚上。
指標選手初始化很重要啊。
加油qwq
#include <algorithm> #include <cstdio> #include <queue> #define nullptr NULL const int MAXN = 100010; int n, k; long long ans; struct Graph { struct Edge { int to; long long w; Edge *next; Edge(int to, long long w, Edge* next): to(to), w(w), next(next) {} ~Edge(void) { if(next != nullptr) delete next; } }*head[MAXN]; Graph(int n) { std :: fill(head, head + n + 1, (Edge*)nullptr); } ~Graph(void) { for(int i = 1; i <= n; ++i) delete head[i]; } void AddEdge(int u, int v, long long w) { head[u] = new Edge(v, w, head[u]); } void Build(int x, int a, int b) { if(x % 2 == 0 && a == b) { puts("-1"); exit(0); } switch(x) { case 1: AddEdge(a, b, 0LL); AddEdge(b, a, 0LL); break; case 2: AddEdge(a, b, 1LL); break; case 3: AddEdge(b, a, 0LL); break; case 4: AddEdge(b, a, 1LL); break; case 5: AddEdge(a, b, 0LL); break; } } }*G; namespace DiffConst { bool exist[MAXN]; int cnt[MAXN]; long long dist[MAXN]; bool SPFA(int S) { std :: queue<int> Q; Q.push(S); exist[S] = true; while(!Q.empty()) { int u = Q.front(), v; Q.pop(); exist[u] = false; for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next) if(dist[v = i -> to] < dist[u] + i -> w) { if(!exist[v]) { if(++cnt[v] == n) return false; Q.push(v); exist[v] = 1; } dist[v] = dist[u] + i -> w; } } return true; } } int main(void) { scanf("%d %d", &n, &k); G = new Graph(n); for(int i = 1, x, a, b; i <= k; ++i) { scanf("%d %d %d", &x, &a, &b); G -> Build(x, a, b); } for(int i = n; i >= 1; --i) G -> AddEdge(0, i, 1LL); if(DiffConst :: SPFA(0)) { for(int i = 1; i <= n; ++i) ans += DiffConst :: dist[i]; printf("%lld\n", ans); } else puts("-1"); return 0; }
謝謝閱讀。