Test instructions: There are n points and m bars have a network of edges, each side has two costs:
D: Cost of destroying this side B: rebuilding the cost of a two-way side
Looking for such two point sets, so that the point set S points set T satisfies the cost of destroying all the paths of S to T and > destroys all T to S of the cost of the path and + rebuilds these T to s the cost of the bidirectional path and.
Idea 1:
And then this is the solution to the feasible flow problem of the Yuanhui with the Nether network flow see here ~ ~
This is what it says. Finally, there is no viable flow is to find the maximum flow of the new network we construct ~ and then determine whether the maximum flow is full flow ~ (that is, determine whether the maximum flow and the additional source points of the total outflow equal ~ ~)
Code
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include < vector> #include <string> #include <queue> #include <map> #include <set> #include <cmath > #include <cstdlib>using namespace std, #define INF 0x3f3f3f3f#define PI acos ( -1.0) #define MEM (A, B) memset (A, B, sizeof (a)) typedef pair<int,int> PII;TYPEDEF Long Long ll;//------------------------------const int MAXN = 210;int n,m;struct edge{int to, CAP, rev;//end capacity reverse edge edge (int to_ = 0, int cap_ = 0, int rev_ = 0) {to = To_ ; Cap = CAP_; Rev = rev_; }};vector<edge> g[maxn];int level[maxn];//Vertex to source point distance designator int iter[maxn];void Add_edge (int from, int. to, int cap) {Ed GE Tmp1 (To, Cap, g[to].size ()); G[from].push_back (TMP1); Edge tmp2 (from, 0, G[from].size ()-1); G[to].push_back (TMP2);} void BFs (int s) {memset (level,-1, sizeof); Queue<int> Q; Level[s] = 0; Q.push (s); while (!q.empty ()) {int v = q.front (); Q.pop (); for (int i = 0; i < g[v].size (); i++) {edge& e = g[v][i]; if (E.cap > 0 && level[e.to] < 0) {level[e.to] = Level[v] + 1; Q.push (e.to); }}}}int dfs (int v, int t, int f) {if (v = = t) return F; for (int& i = iter[v]; i < g[v].size (); i++) {edge& e = g[v][i]; if (E.cap > 0 && level[v] < level[e.to]) {int d = DFS (e.to, T, Min (E.cap, f)); if (d > 0) {e.cap-= D; G[e.to][e.rev].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; memset (ITER, 0, sizeof (ITER)); int F; while ((f = DFS (s, T, INF)) > 0) {flow + = f; }}}//------------------above is the maximum flow template part correct----------------------int Sum;int mi[maxn];//This is the value of the degrees-out that is used to hold each point, which is the M (i) in the paper; VO ID init () {for (int i = 0; i < MAXN; i++) {//Net stream empty, do not forget g[i].clear (); } memset (MI, 0, sizeof (MI)); scanf ("%d%d", &n,&m); int U, V, d, b; for (int i = 1; I <= m; i++) {scanf ("%d%d%d%d", &u, &v, &d, &b); Mi[u]-=d; Mi[v]+=d; Add_edge (U, V, b);//plus Edge added is the nether value of each edge} sum = 0;//sum All outgoing traffic for the source point for (int i = 1; I <= n; i++) {i F (Mi[i] < 0) Add_edge (i, n+1,-mi[i]); else if (Mi[i] > 0) {add_edge (0, I, mi[i]); Sum + = Mi[i]; }}}void Solve () {int ans = max_flow (0, n+1); if (ans = = sum) printf ("happy\n"); else printf ("unhappy\n");} int main () {int t; int cas = 0; scanf ("%d", &t); while (t--){init (); printf ("Case #%d:", ++cas); Solve (); } return 0;}
Idea 2:
To imagine ~ If for all a single point of a set of S, can not meet
The cost of the path of S to T and > destroys all T to S of the cost of the path and the cost of rebuilding these T to S bidirectional path, then the collection of arbitrary points constitutes the S set also must not meet the above conditions ~ ~ ~ If the existence of a set satisfies the above conditions, there must be a single point to meet the above conditions ~~~~
So we actually just use the enumeration point and then judge it. Orz ...
Code
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include < vector>using namespace Std;const int maxn = 205;int N, m;int D[maxn][maxn], b[maxn][maxn];vector<int> IN[MAXN], O Ut[maxn];void Init () {for (int i = 0; i < MAXN; i++) {in[i].clear (); Out[i].clear (); } memset (D,0,sizeof (D)); memset (b,0,sizeof (B)); scanf ("%d%d", &n,&m); int u, V, DD, BB; for (int i = 1; I <= m; i++) {scanf ("%d%d%d%d", &U,&V,&DD,&BB); Out[u].push_back (v); In[v].push_back (U); D[U][V] = DD; B[U][V] = BB; }}bool deal (int u) {int x = 0; for (int i = 0; i < in[u].size (); i++) {int v = in[u][i]; x + = D[v][u]; } int y = 0; for (int i = 0; i < out[u].size (); i++) {int v = out[u][i]; y = y + d[u][v] + b[u][v]; } if (Y < x) return true; RetuRN false;} void Solve () {for (int i = 1; I <= n; i++) {if (Deal (i)) {printf ("unhappy\n"); Return }} printf ("happy\n");} int main () {int t; int cas = 0; scanf ("%d", &t); while (t--) {init (); printf ("Case #%d:", ++cas); Solve (); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 4940 Destroy Transportation System (feasible flow judgment without Yuanhui upper and lower bounds network flow)