这道题纠结了一天,终于还是写出来了。
这道题就是一个求源和汇联通度的题,转换过来就是最大流最小割问题。之前也做过一些最大流的题,但都只是单纯的最大流而已,算不上难题。这题是我的第一道最小割~~
刚开始有好几个地方想错了:
1.求最小割。刚开始是在网络里面找满流边,后来才发现是错的,需要从源点开始进行DFS,具体分析网上有一篇很好的论文。
2.枚举。这道题要求有多个最小割的情况是,按字典顺序输出割点。开始不知道怎么枚举,还用到了DFS,在一条流里面找最小割点,然后把找到的割点排序输出。WA了很久,最后还是放弃。在网上看到一个枚举点,删除点求流量是否减少,如果减少则该点为割点。当然,枚举时按照点的编号从小到大枚举就可以了。
总的来说,做了这题,有两个收获:
1.会求最小割了。
2.学会了一种新的思路。
Just do it. 继续加油。第一篇博文,希望大家支持,谢谢。
这道题就是一个求源和汇联通度的题,转换过来就是最大流最小割问题。之前也做过一些最大流的题,但都只是单纯的最大流而已,算不上难题。这题是我的第一道最小割~~
刚开始有好几个地方想错了:
1.求最小割。刚开始是在网络里面找满流边,后来才发现是错的,需要从源点开始进行DFS,具体分析网上有一篇很好的论文。
2.枚举。这道题要求有多个最小割的情况是,按字典顺序输出割点。开始不知道怎么枚举,还用到了DFS,在一条流里面找最小割点,然后把找到的割点排序输出。WA了很久,最后还是放弃。在网上看到一个枚举点,删除点求流量是否减少,如果减少则该点为割点。当然,枚举时按照点的编号从小到大枚举就可以了。
总的来说,做了这题,有两个收获:
1.会求最小割了。
2.学会了一种新的思路。
Just do it. 继续加油。第一篇博文,希望大家支持,谢谢。
Code
1 #include <stdio.h>
2 #include <string.h>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define M(x, n) memset(x, n, sizeof(x))
8
9 struct Edge {
10 int u, v, w;
11 struct Edge *next, *neg;
12 Edge() {}
13 Edge(const int &U, const int &V, const int &W)
14 :u(U), v(V), w(W){}
15 }mem[1<<19];
16
17 const int MaxN = 210, inf = 0x7fffffff;
18
19 struct Map {
20 int map[MaxN][MaxN], n;
21 Map modify(int x) {
22 Map tmp;
23 tmp.n = n;
24 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
25 if(i == x || j == x)
26 tmp.map[i][j] = 0;
27 else
28 tmp.map[i][j] = map[i][j];
29 }
30 return tmp;
31 }
32 void del(int x) {
33 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
34 if(i == x || j == x)
35 map[i][j] = 0;
36 }
37 }
38 }MM;
39
40 Edge *adj[MaxN<<1], *pre[MaxN<<1];
41 int n, src, dst, mtp;
42 int q[MaxN<<1], qs, qe;
43 int f[MaxN<<1], mark[MaxN<<1], cut[MaxN<<1];
44
45 inline void addedge(const int &u, const int &v, const int &w) {
46 mem[mtp] = Edge(u, v, w);
47 mem[mtp].next = adj[u]; adj[u] = mem + mtp++;
48 mem[mtp] = Edge(v, u, 0);
49 mem[mtp].next = adj[v]; adj[v] = mem + mtp++;
50 adj[u]->neg = adj[v]; adj[v]->neg = adj[u];
51 }
52
53 void build_graph(const Map &M) {
54 mtp = 0;
55 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
56 if(M.map[i][j] && i != j) {
57 addedge(i+n, j, inf);
58 }
59 else if(i == j) {
60 if(i == src)
61 addedge(i, i+n, inf);
62 else
63 addedge(i, i+n, 1);
64 }
65 }
66 }
67
68 bool spfa() {
69 int u, v;
70 Edge *p;
71 M(mark, 0); M(f, 0); M(pre, 0);
72 f[src] = inf; mark[src] = true; pre[src] = NULL;
73 q[0] = src; qs = 0; qe = 1;
74 while(qs != qe) {
75 u = q[qs++]; if(qs == MaxN) qs = 0;
76 for(p = adj[u]; p; p = p->next) {
77 v = p->v;
78 if(!mark[v] && p->w > 0) {
79 f[v] = p->w > f[u] ? f[u] : p->w;
80 pre[v] = p;
81 mark[v] = true;
82 q[qe++] = v; if(qe == MaxN) qe = 0;
83 }
84 }
85 if(f[dst] > 0)
86 return true;
87 }
88 if(f[dst] > 0)
89 return true;
90 return false;
91 }
92
93 int MaxFlow(const Map &MM) {
94 M(adj, 0);
95 build_graph(MM);
96 int flow = 0;
97 while(spfa()) {
98 Edge *p;
99 int u;
100 flow += f[dst];
101 for(p = pre[dst]; p; p = pre[u]) {
102 p->w -= f[dst];
103 p->neg->w += f[dst];
104 u = p->u;
105 }
106 }
107 return flow;
108 }
109
110 int main() {
111 while(scanf("%d%d%d", &n, &src, &dst) == 3) {
112 MM.n = n;
113 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
114 scanf("%d", &MM.map[i][j]);
115 }
116 if(MM.map[src][dst]) {
117 printf("NO ANSWER!\n");
118 continue;
119 }
120 int Flow = MaxFlow(MM);
121 int ctp = 0;
122 printf("%d\n", Flow);
123 for(int i = 1; i <= n; ++i) {
124 if(i == src || i == dst) continue;
125 int t = MaxFlow(MM.modify(i));
126 if(t < Flow) {
127 Flow--;
128 cut[ctp++] = i;
129 MM.del(i);
130 }
131 if(!t)
132 break;
133 }
134 for(int i = 0; i < ctp; ++i) {
135 if(i) {printf(" %d", cut[i]);continue;}
136 printf("%d", cut[i]);
137 }
138 if(ctp)
139 putchar(10);
140 }
141 return 0;
142 }
143
1 #include <stdio.h>
2 #include <string.h>
3 #include <algorithm>
4
5 using namespace std;
6
7 #define M(x, n) memset(x, n, sizeof(x))
8
9 struct Edge {
10 int u, v, w;
11 struct Edge *next, *neg;
12 Edge() {}
13 Edge(const int &U, const int &V, const int &W)
14 :u(U), v(V), w(W){}
15 }mem[1<<19];
16
17 const int MaxN = 210, inf = 0x7fffffff;
18
19 struct Map {
20 int map[MaxN][MaxN], n;
21 Map modify(int x) {
22 Map tmp;
23 tmp.n = n;
24 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
25 if(i == x || j == x)
26 tmp.map[i][j] = 0;
27 else
28 tmp.map[i][j] = map[i][j];
29 }
30 return tmp;
31 }
32 void del(int x) {
33 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
34 if(i == x || j == x)
35 map[i][j] = 0;
36 }
37 }
38 }MM;
39
40 Edge *adj[MaxN<<1], *pre[MaxN<<1];
41 int n, src, dst, mtp;
42 int q[MaxN<<1], qs, qe;
43 int f[MaxN<<1], mark[MaxN<<1], cut[MaxN<<1];
44
45 inline void addedge(const int &u, const int &v, const int &w) {
46 mem[mtp] = Edge(u, v, w);
47 mem[mtp].next = adj[u]; adj[u] = mem + mtp++;
48 mem[mtp] = Edge(v, u, 0);
49 mem[mtp].next = adj[v]; adj[v] = mem + mtp++;
50 adj[u]->neg = adj[v]; adj[v]->neg = adj[u];
51 }
52
53 void build_graph(const Map &M) {
54 mtp = 0;
55 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
56 if(M.map[i][j] && i != j) {
57 addedge(i+n, j, inf);
58 }
59 else if(i == j) {
60 if(i == src)
61 addedge(i, i+n, inf);
62 else
63 addedge(i, i+n, 1);
64 }
65 }
66 }
67
68 bool spfa() {
69 int u, v;
70 Edge *p;
71 M(mark, 0); M(f, 0); M(pre, 0);
72 f[src] = inf; mark[src] = true; pre[src] = NULL;
73 q[0] = src; qs = 0; qe = 1;
74 while(qs != qe) {
75 u = q[qs++]; if(qs == MaxN) qs = 0;
76 for(p = adj[u]; p; p = p->next) {
77 v = p->v;
78 if(!mark[v] && p->w > 0) {
79 f[v] = p->w > f[u] ? f[u] : p->w;
80 pre[v] = p;
81 mark[v] = true;
82 q[qe++] = v; if(qe == MaxN) qe = 0;
83 }
84 }
85 if(f[dst] > 0)
86 return true;
87 }
88 if(f[dst] > 0)
89 return true;
90 return false;
91 }
92
93 int MaxFlow(const Map &MM) {
94 M(adj, 0);
95 build_graph(MM);
96 int flow = 0;
97 while(spfa()) {
98 Edge *p;
99 int u;
100 flow += f[dst];
101 for(p = pre[dst]; p; p = pre[u]) {
102 p->w -= f[dst];
103 p->neg->w += f[dst];
104 u = p->u;
105 }
106 }
107 return flow;
108 }
109
110 int main() {
111 while(scanf("%d%d%d", &n, &src, &dst) == 3) {
112 MM.n = n;
113 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) {
114 scanf("%d", &MM.map[i][j]);
115 }
116 if(MM.map[src][dst]) {
117 printf("NO ANSWER!\n");
118 continue;
119 }
120 int Flow = MaxFlow(MM);
121 int ctp = 0;
122 printf("%d\n", Flow);
123 for(int i = 1; i <= n; ++i) {
124 if(i == src || i == dst) continue;
125 int t = MaxFlow(MM.modify(i));
126 if(t < Flow) {
127 Flow--;
128 cut[ctp++] = i;
129 MM.del(i);
130 }
131 if(!t)
132 break;
133 }
134 for(int i = 0; i < ctp; ++i) {
135 if(i) {printf(" %d", cut[i]);continue;}
136 printf("%d", cut[i]);
137 }
138 if(ctp)
139 putchar(10);
140 }
141 return 0;
142 }
143