[BZOJ2330][SCOI2011][拓扑排序][强连通分量][Tarjan]Candy
2014-04-29 16:04
417 查看
[Problem Description]
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
[Algorithm]
强连通分量tarjan,拓扑排序
[Analysis]
这是经典的拓扑排序的模型。蛋疼的是加入了可以等于和等于小于的关系。没关系,只要解决了等于的问题,照样可以拓扑排序做。先将等于和等于小于的边加入图中(等于为双向边,等于小于为单向边),然后跑强连通分量,这样每一个强连通分量一定糖果数相等,且原图变成了一个有向无环图(如果数据有解的话),跑拓扑排序即可。
[Pay Attention]
最后的结果要用long long,还有就是跑完强连通分量要注意检查一下,可能存在强连通分量内部出现大于或小于的边,这样的话就是无解
幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
[Algorithm]
强连通分量tarjan,拓扑排序
[Analysis]
这是经典的拓扑排序的模型。蛋疼的是加入了可以等于和等于小于的关系。没关系,只要解决了等于的问题,照样可以拓扑排序做。先将等于和等于小于的边加入图中(等于为双向边,等于小于为单向边),然后跑强连通分量,这样每一个强连通分量一定糖果数相等,且原图变成了一个有向无环图(如果数据有解的话),跑拓扑排序即可。
[Pay Attention]
最后的结果要用long long,还有就是跑完强连通分量要注意检查一下,可能存在强连通分量内部出现大于或小于的边,这样的话就是无解
[code]/************************************************************** Problem: 2330 User: gaotianyu1350 Language: C++ Result: Accepted Time:352 ms Memory:14156 kb ****************************************************************/ #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream> #include <queue> using namespace std; #define MAXN 201000 struct relation { int Type; int x, y; }; relation q[MAXN]; int cct[MAXN] = {0}, size[MAXN] = {0}, candy[MAXN], cnt = 0; long long f[MAXN] = {0}; int rudu[MAXN] = {0}; int point[MAXN], nxt[MAXN], v[MAXN]; int dfsTime[MAXN] = {0}, lessTime[MAXN] = {0}, st[MAXN], top = 0; int nowTime = 0; bool same[MAXN]; int tot, n, k; inline void swap(int &a, int &b) { int temp = a; a = b; b = temp; } inline void clear() { memset(point, 0, sizeof(point)); memset(nxt, 0, sizeof(nxt)); memset(rudu, 0, sizeof(rudu)); memset(same, 0, sizeof(same)); tot = 0; } inline void addedge(int x, int y, bool canbesame) { tot++; nxt[tot] = point[x]; point[x] = tot; v[tot] = y; same[tot] = canbesame; rudu[y]++; } void tarjan(int now) { dfsTime[now] = lessTime[now] = ++nowTime; st[++top] = now; for (int temp = point[now]; temp; temp = nxt[temp]) { int tar = v[temp]; if (!dfsTime[tar]) { tarjan(tar); lessTime[now] = min(lessTime[now], lessTime[tar]); } else if (!cct[tar]) lessTime[now] = min(lessTime[now], dfsTime[tar]); } if (lessTime[now] == dfsTime[now]) { cnt++; while (1) { cct[st[top--]] = cnt; size[cnt]++; if (st[top + 1] == now) break; } } } long long Solve() { queue<int> q; long long ans = 0; int already = 0; for (int i = 1; i <= cnt; i++) if (!rudu[i]) { f[i] = 1; q.push(i); } if (q.empty()) return -1; while (!q.empty()) { int now = q.front(); q.pop(); ans += size[now] * f[now]; already += size[now]; for (int temp = point[now]; temp; temp = nxt[temp]) { int tar = v[temp]; if (same[temp]) f[tar] = f[tar] > f[now] ? f[tar] : f[now]; else f[tar] = f[tar] > f[now] ? f[tar] : f[now] + 1; rudu[tar]--; if (!rudu[tar]) q.push(tar); } } if (already < n) return -1; else return ans; } int main() { //freopen("input.txt", "r", stdin); clear(); scanf("%d%d", &n, &k); for (int i = 1; i <= k; i++) { scanf("%d%d%d", &q[i].Type, &q[i].x, &q[i].y); if (q[i].Type == 3 || q[i].Type == 4) swap(q[i].x, q[i].y); if (q[i].Type == 1) addedge(q[i].x, q[i].y, false), addedge(q[i].y, q[i].x, false); if (q[i].Type == 3 || q[i].Type == 5) addedge(q[i].x, q[i].y, false); } for (int i = 1; i <= n; i++) if (!dfsTime[i]) tarjan(i); clear(); for (int i = 1; i <= k; i++) if (cct[q[i].x] != cct[q[i].y]) { if (q[i].Type == 3 || q[i].Type == 5) addedge(cct[q[i].x], cct[q[i].y], true); else addedge(cct[q[i].x], cct[q[i].y], false); } else { if (q[i].Type == 2 || q[i].Type == 4) { printf("-1\n"); return 0; } } long long ans = Solve(); printf("%lld\n", ans); }
相关文章推荐
- 【BZOJ2330】【SCOI2011】糖果——差分约束系统+tarjan
- BZOJ 2330: [SCOI2011]糖果
- bzoj2330 [SCOI2011]糖果题解
- 差分约束 【bzoj2330】[SCOI2011]糖果
- 【BZOJ2330】 [SCOI2011]糖果
- BZOJ 2330 [SCOI2011]糖果 差分约束系统
- bzoj2330 [SCOI2011]糖果 差分约束
- bzoj2330: [SCOI2011]糖果(差分约束)
- 【bzoj2330】[SCOI2011]糖果 差分约束系统
- bzoj2330 SCOI2011 糖果 【差分约束】
- 【bzoj2330】【P3275 】【SCOI2011】糖果
- [BZOJ2330][SCOI2011]糖果(差分约束)
- bzoj2330: [SCOI2011]糖果
- bzoj2330 [SCOI2011]糖果
- bzoj 2330 [SCOI2011]糖果(差分约束系统)
- [BZOJ 2330][SCOI 2011]糖果(差分约束系统)
- BZOJ 1854: [Scoi2010]游戏 [连通分量 | 并查集 | 二分图匹配]
- [BZOJ1051] [HAOI2006] 受欢迎的牛 - tarjan强连通分量
- BZOJ 2330 [SCOI2011]糖果 差分约束spfa版
- bzoj2330 [SCOI2011]糖果 差分约束