uva 11248 最小割

Dinic

  1 #include<iostream>
  2 #include<string>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<cstdio>
  6 #include<set>
  7 #include<map>
  8 #include<vector>
  9 #include<cstring>
 10 #include<stack>
 11 #include<cmath>
 12 #include<queue>
 13 using namespace std;
 14 #define INF 0x3f3f3f3f
 15 #define LL long long
 16 #define MAXN 110
 17 struct Edge{
 18     int from, to, cap, flow;
 19 };
 20 bool comp(const Edge& a, const Edge& b){
 21     return a.from < b.from || (a.from == b.from && a.to < b.to);
 22 }
 23 struct Dinic{
 24     int n, m, s, t;
 25     vector<Edge> edges;
 26     vector<int> G[MAXN];
 27     bool vis[MAXN];
 28     int d[MAXN];
 29     int cur[MAXN];
 30     void init(int n){
 31         this->n = n;
 32         for (int i = 0; i <= n; i++)
 33             G[i].clear();
 34         edges.clear();
 35     }
 36     void AddEdge(int from, int to, int cap){
 37         edges.push_back(Edge{ from, to, cap, 0 });
 38         edges.push_back(Edge{ to, from, 0, 0 });
 39         m = edges.size();
 40         G[from].push_back(m - 2);
 41         G[to].push_back(m - 1);
 42     }
 43     bool BFS(){
 44         memset(vis, 0, sizeof(vis));
 45         queue<int> Q;
 46         Q.push(s);
 47         d[s] = 0;
 48         vis[s] = 1;
 49         while (!Q.empty()){
 50             int x = Q.front();
 51             Q.pop();
 52             for (int i = 0; i<G[x].size(); i++){
 53                 Edge& e = edges[G[x][i]];
 54                 if (!vis[e.to] && e.cap>e.flow){
 55                     vis[e.to] = 1;
 56                     d[e.to] = d[x] + 1;
 57                     Q.push(e.to);
 58                 }
 59             }
 60         }
 61         return vis[t];
 62     }
 63     int DFS(int x, int a){
 64         if (x == t || a == 0)return a;
 65         int flow = 0, f;
 66         for (int& i = cur[x]; i<G[x].size(); i++){
 67             Edge& e = edges[G[x][i]];
 68             if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>0){
 69                 e.flow += f;
 70                 edges[G[x][i] ^ 1].flow -= f;
 71                 flow += f;
 72                 a -= f;
 73                 if (a == 0)break;
 74             }
 75         }
 76         return flow;
 77     }
 78     int Maxflow(int s, int t, int need){
 79         this->s = s; this->t = t;
 80         int flow = 0;
 81         while (BFS()){
 82             memset(cur, 0, sizeof(cur));
 83             flow += DFS(s, INF);
 84             if (flow > need)return flow;
 85         }
 86         return flow;
 87     }
 88     //最小割割边
 89     vector<int> Mincut(){
 90         BFS();
 91         vector<int> ans;
 92         for (int i = 0; i<edges.size(); i++){
 93             Edge& e = edges[i];
 94             if (vis[e.from] && !vis[e.to] && e.cap>0)ans.push_back(i);
 95         }
 96         return ans;
 97     }
 98     void Reduce(){
 99         for (int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow;
100     }
101     void ClearFlow(){
102         for (int i = 0; i < edges.size(); i++) edges[i].flow = 0;
103     }
104 };
105 Dinic ex;
106 int main(){
107     int N, E, C, cas = 0;
108     while (~scanf("%d%d%d", &N, &E, &C))
109     {
110         if (!N)break;
111         ex.init(N);
112         int a, b, c;
113         while (E--)
114         {
115             scanf("%d%d%d", &a, &b, &c);
116             ex.AddEdge(a, b, c);
117         }
118         int flow = ex.Maxflow(1, N, INF);
119         printf("Case %d: ", ++cas);
120         if (flow > C)printf("possible\n");
121         else{
122             vector<int> cut = ex.Mincut();
123             ex.Reduce();
124             vector<Edge>ans;
125             for (int i = 0; i < cut.size(); i++){
126                 Edge& e = ex.edges[cut[i]];
127                 int temp = e.cap;
128                 e.cap = C;
129                 ex.ClearFlow();
130                 if (flow + ex.Maxflow(1, N, C - flow) >= C)ans.push_back(e);
131                 e.cap = temp;
132             }
133             if (ans.empty())printf("not possible\n");
134             else{
135                 sort(ans.begin(), ans.end(), comp);
136                 printf("possible option:(%d,%d)", ans[0].from, ans[0].to);
137                 for (int i = 1; i < ans.size(); i++)
138                     printf(",(%d,%d)", ans[i].from, ans[i].to);
139                 printf("\n");
140             }
141         }
142     }
143     return 0;
144 }
时间: 2024-10-05 05:19:52

uva 11248 最小割的相关文章

UVa 1515 (最小割) Pool construction

题意: 输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 但要保证最外一圈是草,求最小费用. 分析: 还不是特别理解紫书上的讲解.. 首先把最外一圈的洞变成草,并累加花费. 增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞. 源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边.表示把这条弧切断,割的容量增加d,草就会变成洞. 每个洞与汇点连一条容量为f的边. 相邻两个格子之间连一条双向

UVA 11248 Frequency Hopping (最大流+最小割)

题意:与正常的网络流一样,不过给定的第一行的最后一个数C的意思是能能否在给定的图里求出修改某一条边或者不修改某一条边是的这个图的流变成C,如果没修改就能有C,那么输出possible,通过修改能得到C输出possible+能修改的边集合,否则输出no possible 思路:(自己的是死暴力方法,直接爆了,想了很多法子都来不起,最后参照白书的思路来起了)可以先求出最大流,然后求出最小割里的弧,依次修改最小割里的弧,看能求出的最大流是否大于C PS:不优化的话很容易超时,第一个优化是把第一次求得得

UVA 1212 - Duopoly(最小割)

UVA 1212 - Duopoly 题目链接 题意:两个公司,每个公司都有n个开价租用一些频道,一个频道只能租给一个公司,现在要求出一个分配方案使得收益最大 思路:最小割,源点连到第一个公司,第二个公司连到汇点,容量均为价钱,然后第一个公司和第二个公司有冲突的就连一条边容量为无穷大,然后求这个图的最小割就是去掉最小多少使得图原图不会冲突了,然后用总金额减去最小割的值即可 代码: #include <cstdio> #include <cstring> #include <q

uva 1212 Duopoly (最小割最大流)

uva 1212 Duopoly Description The mobile network market in country XYZ used to be dominated by two large corporations, XYZ Telecom and XYZ Mobile. The central government recently has realized that radio frequency spectrum is a scarce resource and want

UVA 11419 SAM I AM (二分图,最小割)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2414 Problem C SAM I AM Input: Standard Input Output: Standard Output The world is in great danger!! Mental's forces have returned to Earth to eradi

UVA - 10480 Sabotage 最小割,输出割法

UVA - 10480 Sabotage 题意:现在有n个城市,m条路,现在要把整个图分成2部分,编号1,2的城市分成在一部分中,拆开每条路都需要花费,现在问达成目标的花费最少要隔开那几条路. 题解:建图直接按给你的图建一下,然后呢跑一下最大流,我们就知道了最小割是多少,答案就是最小割了  . 现在要求输出割法.我们从s开始往前跑,如果某条正向边有流量,我们就按着这条边继续往外走,知道无法再走,把所有经历过的点都染一下色.最后看所有的边,是不是有一头是染色了,另一头没有染色,如果是,这条边就是割

Uva -1515 Pool construction(最小割)

输入一个字符矩阵,'.'代表洞,'#'代表草地.可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b. 首先把最外一圈的洞变成草,并累加花费. 增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞. 源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边.表示把这条弧切断,割的容量增加d,草就会变成洞. 每个洞与汇点连一条容量为f的边. 相邻两个格子之间连一条双向边. 用最大流算法求最小割在加上之前把边界上的洞变成草的费用,就是最小花费. 用最小

Uvaoj 11248 Frequency Hopping(Dinic求最小割)

题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量 可以达到目的,那么输出possible option:接着输出每一条可以达到目的的边(按升序),再否则输出not possible 思路:先求一次最大流,如果流量至少为C,则直接输出possible,否则需要修改的弧一定在最小割里! 接着吧这些弧(最小割里的)的容量设为无穷大,然后在求最大流,看最大流的流量能否满足是C即可,如果满足了,那就把这一条边记录下来

UVa 1660 Cable TV Network (最大流,最小割)

题意:求一个无向图的点连通度. 析:把每个点拆成两个,然后中间连接一个容量为1的边,然后固定一个源点,枚举每个汇点,最小割. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream>