문제: icpc.me/1671
소스->상어->상어->싱크로 그래프를 모델링 한 뒤 최대유량을 구하여 N값에서 빼주면 남은 상어의 값을 구할 수 있다.
이때 주의해야 할 케이스가 있는데 두 상어의 크기 속도 지는이 전부 같다면 상어가 서로를 먹으려 할수도 있다. 이런 케이스에만 두 상어의 우위를 따로 주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <cstring> #define INF 987654321 #define S 2002 #define E 2003 using namespace std; int n; struct Edge { int v, cap, rev; Edge(int v, int cap, int rev) :v(v), cap(cap), rev(rev) {} }; vector<vector<Edge>> vt; int level[2010]; int work[2010]; void addEdge(int s, int e, int c) { vt[s].emplace_back(e, c, (int)vt[e].size()); vt[e].emplace_back(s, 0, (int)vt[s].size() - 1); } bool bfs() { memset(level, -1, sizeof(level)); level[S] = 0; queue<int> qu; qu.push(S); while (qu.size()) { int here = qu.front(); qu.pop(); for (auto i : vt[here]) { int there = i.v; int cap = i.cap; if (level[there] == -1 && cap > 0) { level[there] = level[here] + 1; qu.push(there); } } } return level[E] != -1; } int dfs(int here, int crtcap) { if (here == E)return crtcap; for (int &i = work[here]; i < vt[here].size(); i++) { int there = vt[here][i].v; int cap = vt[here][i].cap; if (level[here] + 1 == level[there] && cap>0) { int df = dfs(there, min(crtcap, cap)); if (df > 0) { vt[here][i].cap -= df; vt[there][vt[here][i].rev].cap += df; return df; } } } return 0; } struct shark { int a, b, c; }; int main() { scanf("%d", &n); vt.resize(2010); shark sk[2010]; for (int i = 1; i <= n; i++) { int x, y, z; scanf("%d%d%d", &x, &y, &z); sk[i].a = x, sk[i].b = y, sk[i].c = z; } for (int i = 1; i <= n; i++) addEdge(S, i, 2); for (int i = 1; i <= n; i++) addEdge(i + 1000, E, 1); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i == j) continue; if (sk[i].a == sk[j].a&&sk[i].b == sk[j].b&&sk[i].c == sk[j].c) { if (i > j) continue; } if (sk[i].a >= sk[j].a&&sk[i].b >= sk[j].b&&sk[i].c >= sk[j].c) addEdge(i, 1000 + j, 1); } } int ans = 0; while (bfs()) { memset(work, 0, sizeof(work)); while (1) { int flow = dfs(S, INF); if (!flow)break; ans += flow; } } printf("%d", n - ans); return 0; } | //cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)13560 Football (0) | 2017.02.20 |
---|---|
BOJ)12019 동아리방 청소! (0) | 2017.02.17 |
BOJ)1867 돌멩이 제거 (0) | 2017.02.16 |
BOJ)11377 열혈강호3 (0) | 2017.02.16 |
BOJ)11376 열혈강호2 (0) | 2017.02.15 |