发布于 

Smallest Minimum Cut

Smallest Minimum Cut

hdu 6214

题目来源: hdu

分析

题目要求求出边数最小的最小割。很明显,我们在正常求最小割时根本无法得知最小割的边数。所以我们应该想办法把它记录下来。

我们可以把这个信息加入到所有边的capacity中。因为边共有m个,所以我们的最小割最大为m。那么我们可以令\(capacity = capacity \times (m+1) + 1\)。此时我们算出的最小割,便为\(原来的最小割\times (m+1) + 边数\)。所以,我们直接\(mod (m+1)\)就好了。

代码

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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <queue>
#include <cstdio>

#define MAXN 1010
#define INF 0x3f3f3f3f

using namespace std;

struct Node;
struct Edge;
int n,m;

struct Node
{
Edge *firstEdge, *currentEdge;
int level;

Node()
{
firstEdge = NULL;
}

}node[MAXN];

struct Edge
{
Node *from, *to;
int capacity, flow;
Edge *next, *reverseEdge;

Edge(Node *from, Node *to, int capacity):from(from),to(to),capacity(capacity),flow(0),next(from->firstEdge) {}

~Edge()
{
delete next;
}
};

struct Dinic
{
bool makeLevelGraph(Node *s, Node *t, int n)
{
for (int i = 1; i<=n; i++)
{
node[i].level = 0;
node[i].currentEdge = node[i].firstEdge;
}
queue<Node *> q;
q.push(s);
s->level = 1;

while (!q.empty())
{
Node *v = q.front();
q.pop();

for (Edge *e = v->firstEdge; e; e = e->next)
if (e->flow<e->capacity && e->to->level==0)
{
e->to->level = v->level + 1;
if (e->to==t)
return true;
else q.push(e->to);
}
}

return false;
}

int findPath(Node *s, Node *t, int limit = INF)
{
if (s==t)
return limit;

for (Edge *&e = s->currentEdge; e; e = e->next)
if (e->to->level==s->level+1 && e->flow < e->capacity)
{
int flow = findPath(e->to, t, min(limit, e->capacity - e->flow));
if (flow>0)
{
e->flow += flow;
e->reverseEdge->flow -= flow;
return flow;
}
}

return 0;
}

int operator()(int s, int t, int n)
{
int ans = 0;
while (makeLevelGraph(&node[s], &node[t], n))
{
int flow;
while ((flow = findPath(&node[s], &node[t]))>0 )
ans += flow;
}
return ans;
}

}dinic;

int main()
{
ios::sync_with_stdio(false);

int T;
scanf("%d",&T);
while (T--)
{
int s,t;
scanf("%d%d%d%d",&n,&m,&s,&t);

for (int i = 1; i<=n; i++)
{
delete node[i].firstEdge;
node[i] = Node();
}

for (int i = 1; i<=m; i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
node[x].firstEdge = new Edge(&node[x], &node[y], z*(1+m)+1);
node[y].firstEdge = new Edge(&node[y], &node[x], 0);

node[x].firstEdge->reverseEdge = node[y].firstEdge;
node[y].firstEdge->reverseEdge = node[x].firstEdge;
}

int ans = dinic(s, t, n);

cout << ans%(1+m) << endl;
}
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Songer](https://blog.songer.xyz/) 创建,使用 Stellar 作为主题。