1
开始抄书吧。。。
基本的有上下界的网络流模型。
在原图的基础上构造超级源点S和超级汇点T,并添加边和修改容量。blabla...
#include<cstdio> #include<map> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<list> #include<set> #include<cmath> using namespace std; const int maxn = 2e2 + 5; const int INF = 1e9; const double eps = 1e-6; typedef unsigned long long ULL; typedef long long LL; typedef pair<int, int> P; #define fi first #define se second struct Edge { int from, to, cap, flow; }; struct Dinic { int n, m, s, t; vector<Edge> edges; // 边数的两倍 vector<int> G[maxn]; // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号 bool vis[maxn]; // BFS使用 int d[maxn]; // 从起点到i的距离 int cur[maxn]; // 当前弧指针 void ClearAll(int n) { for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void ClearFlow() { for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; } void AddEdge(int from, int to, int cap) { //cout << from << ' ' << to << ' ' << cap << endl; edges.push_back((Edge){from, to, cap, 0}); edges.push_back((Edge){to, from, 0, 0}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); vis[s] = 1; d[s] = 0; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow) { vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if(x == t || a == 0) return a; int flow = 0, f; for(int& i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } bool check(int n){ for(int i = 0;i < G[0].size();i++){ Edge& e = edges[G[0][i]]; if(e.flow != e.cap) return false; } for(int i = 1;i <= n;i++){ Edge& e = edges[G[i][0]]; if(e.to == n+1 && e.flow != e.cap){ return false; } } return true; } }; Dinic g; int xiajie[maxn*10000], s[maxn]; vector<int> task; int main(){ int n, m; while(scanf("%d%d", &n, &m) != EOF){ g.ClearAll(n+5); int source = 0, sink = n+1; memset(s, 0, sizeof s); task.clear(); for(int i = 1;i <= m;i++){ int u, v, l, c; scanf("%d%d%d%d", &u, &v, &l, &c); xiajie[i] = l; s[v] += l; s[u] -= l; g.AddEdge(u, v, c-l); task.push_back(g.edges.size()-2); } for(int i = 1;i <= n;i++){ if(s[i] > 0){ g.AddEdge(source, i, s[i]); } else{ g.AddEdge(i, sink, -s[i]); } } g.Maxflow(source, sink); if(!g.check(n)) cout << "NO" << endl; else{ cout << "YES" << endl; for(int i = 0;i < task.size();i++){ cout << xiajie[i+1]+g.edges[task[i]].flow << endl; } } } return 0; }