다 이 닝 (네트워크 스 트림 포인트 + Dinic)
3905 단어 도 론
이 문 제 는 좀 풀 면 말 하지 않 겠 습 니 다. 저도 생각 이 안 나 지만 Dinic 알고리즘 은 여름 방학 때 보다 훨씬 뚜렷 해 졌 습 니 다.
Dinic 은 먼저 원래 의 네트워크 에 대해 원점 에서 외환 점 BFS 까지 층 을 나 누 었 다. 외환 점 의 층 을 나 눌 수 있다 면 반드시 유량 이 원점 에서 외환 점 으로 흘러 갈 수 있다 는 것 을 의미한다. 그 다음 에 원점 에서 DFS 를 하고 한 개 (또는 여러 개) 를 찾 아 외환 점 에서 가장 작은 유량 (대략 이런 뜻) 을 증가 시 키 고 최대 흐름 에 이 답 을 더 했다.이번에 DFS 가 추 가 된 번복 은 다음 BFS 이후 에 사용 하기 위 한 것 이다.매번 BFS 가 DFS 에 대해 한 번 에 증 광 로 를 찾 고 BFS 가 외환 점 이 있 는 층 수 를 구분 하지 못 한 다 는 것 을 알 면 증 광 로 가 존재 하지 않 는 다 는 것 을 알 수 있 고 알고리즘 이 끝 났 습 니 다.시간 복잡 도 O (V ^ 2, E).
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1000 + 10;
const int inf = 0x3f3f3f3f;
int N, F, D, k, dep[maxn], head[maxn];
int food[maxn], drink[maxn];
int S, T;
struct Edge
{
int before;
int flow;
int to;
} e[maxn << 1];
inline void add(int u, int v, int c)
{
e[k].to = v;
e[k].flow = c;
e[k].before = head[u];
head[u] = k++;
}
int BFS(int S, int T)
{
queue q;
memset(dep, -1, sizeof(dep));
dep[S] = 0;
q.push(S);
while (!q.empty())
{
int u = q.front();
q.pop();
if (u == T)
return true;
for (int i = head[u]; i != -1; i = e[i].before)
{
int v = e[i].to;
if (e[i].flow && dep[v] == -1)
{
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
if (dep[T] == -1)
return false; //
return true;
}
int DFS(int u, int flow)
{
if (u == T)
return flow; //
int sum = 0;
for (int i = head[u]; i != -1; i = e[i].before)
{
int v = e[i].to;
if (e[i].flow && dep[v] == dep[u] + 1)
{
int f = DFS(v, min(flow - sum, e[i].flow)); //
e[i].flow -= f; // flow-sum
e[i ^ 1].flow += f;
sum += f;
if (sum == flow) //
return sum;
}
}
return sum;
}
int Dinic(int S, int T)
{
int max_flow = 0;
while (BFS(S, T))
{
max_flow += DFS(S, inf);
}
return max_flow;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
#endif
memset(head, -1, sizeof head);
scanf("%d %d %d", &N, &F, &D);
int f, d;
S = 0; //
T = 2 * N + F + D + 1; //
// 2n+1~2n+F
// 1 ~ n
// n+1 ~ 2n
// 2n+F+1 ~ 2n+F+D
for (int i = 1; i <= F; i++)
{
add(S, 2 * N + i, 1); //
add(2 * N + i, S, 0); //
}
for (int i = 1; i <= D; i++)
{
add(2 * N + F + i, T, 1); //
add(T, 2 * N + F + i, 0); //
}
for (int i = 1; i <= N; i++)
{
add(i, i + N, 1); //
add(i + N, i, 0); //
}
for (int i = 1; i <= N; i++)
{
scanf("%d %d", &f, &d);
for (int j = 1; j <= f; j++)
{
scanf("%d", &food[j]);
add(2 * N + food[j], i, 1);
add(i, 2 * N + food[j], 0);
}
for (int j = 1; j <= d; j++)
{
scanf("%d", &drink[j]);
add(N + i, 2 * N + F + drink[j], 1);
add(2 * N + F + drink[j], N + i, 0);
}
}
printf("%d", Dinic(S, T));
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU 1874: 원활 한 공사 계속 [Dijkstra & SPFA & Floyd]모 성 은 여러 해 동안 의 원활 한 공사 계획 을 실행 한 후에 마침내 많은 길 을 건설 하 였 다.길 을 많이 건 너 지 않 아 도 좋 지 않다. 한 도시 에서 다른 도시 로 갈 때마다 여러 가지 도로 방안 을 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.