前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的:
http://blog.csdn.net/leolin_/article/details/7208246
里面包含了其中一些解释。看了这道题的题解之后就会发现确实好像就是一个无源的有上下界的可行流。
#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
#define maxn 500
#define maxe 40000
#define inf 0x3f3f3f3f
struct Edge
{
int u, v, cap;
int nxt;
}edge[maxe];
int head[maxn];
struct Dicnic
{
int level[maxn];
int iter[maxn];
int add;
void init(){
add = 0; memset(head, -1, sizeof(head));
memset(iter, -1, sizeof(iter));
}
void insert(int u, int v, int c){
edge[add].u = u; edge[add].v = v; edge[add].cap = c;
edge[add].nxt = head[u]; head[u] = add++;
edge[add].u = v; edge[add].v = u; edge[add].cap = 0;
edge[add].nxt = head[v]; head[v] = add++;
}
void bfs(int s){
memset(level, -1, sizeof(level));
queue<int> que;
level[s] = 0;
que.push(s);
while (!que.empty()){
int v = que.front(); que.pop();
for (int i = head[v]; i != -1; i = edge[i].nxt){
Edge &e = edge[i];
if (e.cap > 0 && level[e.v] < 0){
level[e.v] = level[v] + 1;
que.push(e.v);
}
}
}
}
int dfs(int v, int t, int f){
if (v == t) return f;
for (int &i = iter[v]; i != -1; i = edge[i].nxt){
Edge &e = edge[i]; Edge &reve = edge[i ^ 1];
if (e.cap > 0 && level[v] < level[e.v]){
int d = dfs(e.v, t, min(f, e.cap));
if (d>0){
e.cap -= d; reve.cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s, int t){
int flow = 0;
for (;;){
bfs(s);
if (level[t] < 0) return flow;
memcpy(iter, head, sizeof(iter));
int f;
while ((f = dfs(s, t, inf))>0){
flow += f;
}
}
}
}net;
int n, m;
int main()
{
int T; cin >> T; int ca = 0;
while (T--){
scanf("%d%d", &n, &m);
net.init();
int ui, vi, di, bi;
int ss = n + 1, tt = ss + 1;
int minflow = 0;
for (int i = 0; i < m; ++i){
scanf("%d%d%d%d", &ui, &vi, &di, &bi);
minflow += di;
net.insert(ui, vi, bi);
net.insert(ss, vi, di);
net.insert(ui, tt, di);
}
if (net.max_flow(ss, tt) == minflow) printf("Case #%d: happy\n", ++ca);
else printf("Case #%d: unhappy\n", ++ca);
}
return 0;
}